Skip to main content

Feeling smart is a warning sign 🧠

You know that feeling of accomplishment gained from understanding a large or complex piece of technology? I like to think of that as a warning sign.

I mean, it is nice to feel smart. But it should also make you stop and think – why was this hard? Is the complexity of the solution justified by the problem? Is there perhaps a simpler solution which will work just as well? Are there other options which would be easier to understand? Do I actually have the problem for which this solution is intended?

For example, maybe you can use Docker Compose instead of Kubernetes? Deploy a monolith instead of micro services? Use vanilla JavaScript instead of React? An in-memory data structure instead of an external database? These suggestions will not be suitable for every project, but when they are, they can reduce the project complexity by a lot!

About complexity #

Some problems or domains are inherently complex. I don’t dismiss a scientific finding in a field I’m not familiar with just because I don’t understand it at first glance. But in most cases, the code I write on a daily basis have no reason for being hard to understand.

Sometimes it is hard to realize that something is overly complex. You have spent a lot of time thinking about the problem, so you have learned the quirks and pitfalls. This can produce a kind of “Stockholm syndrome” effect, where you think the solution is good because you understand it.

So how do you know if something is easy to understand or not? A wonderfully simple rule is provided in the great book A philosophy of software design by John Ousterhout.

If you write a piece of code and it seems simple to you, but other people think it is complex, then it is complex.

When you realize that other people find something complex, it is helpful to think about where the complexity comes from. Try to separate the inherent complexity which is a part of the problem itself and you cannot really escape, from the accidental complexity which comes from a sub-optimal solution.

Complexity tokens #

Think about the complexity for your current project. As a thought exercise, pretend that you only have a limited amount of “complexity tokens” available to you. This puts a limit to the total amount of complexity you are allowed to have in you project. (It also limits how much complexity a developer needs to understand in order to work on the project!)

Given a limited supply of complexity tokens, where would you spend them? For every part of your project where you add complexity, you have to save somewhere else. If you do this over here, you cannot do that over there. You can save on tokens by re-use existing tools instead of adding more.

It can be an interesting challenge to see how simple you can make your system. How few complexity tokens can you use while still solving the actual problem?

Make it simpler #

In the end, the complexity profile of every project will be different. The important part is that if other people shall maintain and extend your solution, they need to be able to understand it. And to be honest, if it does not feel intuitive to other developers, it is likely that it will not feel intuitive to you in six months time either. 🙃

So whenever you feel smart for having solved a problem, take a step back and see if you can make the solution even simpler.

glyn: If the complexity is baked in and cannot be simplified, other options are to:
  1. Carefully and clearly document what you've found out so others can achieve your level of understanding with much less effort. Interestingly, in writing such documentation, one's understanding improves further.
  2. Provide a simpler, well-documented, interface to (part of) the complex system, so it can be used more easily. This isn't risk free, e.g. if the abstraction isn't quite right.