I once worked with a team that, for some reason, valued complexity. It seemed like their egos were tied directly to how hard something was to do. If something was hard and they completed it then that proved that they were smart 🤷♂️? I tried multiple times to introduce the idea of simplicity to them, but it never stuck.
In response to the above, I developed a simple rule that I follow and I tell every team I work with and every engineer that I teach and it is:
“If what you are doing is getting more and more complicated, then you are heading down the wrong path. Conversely, if what you are doing is getting simpler, then you are probably headed in the right direction.”
Me
That’s it. If what you are doing is hard, then stop, think, maybe backup and figure out what you’re missing. However, if what you are doing is simple, easy to reason about, and straight forward, then keep going.
You will notice that the complicated path is phrased as an absolute whereas the simple path is less certain. That is because we have to take into account that
“For every complex problem there is an answer that is clear, simple, and wrong.“
H. L. Mencken
Thankfully, the opposite is also true. There is a solution that is clear, simple, and correct. And, as engineers, this is the solution that we should be constantly aiming for.
In everything we work on there are two kinds of complexity; Inherent Complexity and Accidental Complexity.
Inherent Complexity
This is the complexity that is part of the problem. Think calculating compound interest. There is nothing that can be done to simplify the calculation, it is just complex. However, we can still isolate that complexity, trim it down, and find the simplest form of it to initially implement.
Accidental Complexity
This is the complexity that we as developers introduce to the code base by not taking time to refactor or problem understand the problem we are trying to solve. We go for the easiest implementation, shove the new code into place and then call the problem solved. And we don’t take the time to be professionals. I always use the analogy that this is like going to the doctor and finding out that they couldn’t be bothered to sterilize their instruments before seeing you.
This idea of simple is reinforced by the second rule of Test-Driven Development (TDD). Get the test to pass by implementing the simplest thing that will work. And by the third step of refactoring. If we make a mess, we also need to take the time to clean it up. We need to pride ourselves on the simplicity of our solutions and not how hard it was to implement. This isn’t to say that refactoring is simple.
“…for each desired change, make the change easy (warning: this may be hard), then make the easy change”
Kent Beck
Leave a Reply