You Are Always Wrong
Introduction#
How many times have you been a part of a project where someone says,
Let’s build this once - to handle all the use cases. Then we won’t have to touch it again.
That idea must be one of the biggest lies of our industry. It’s equivalent to the warning on q-tip packages about not using them in your ears. Everyone knows the words don’t reflect reality. I’d wager that most people buy q-tips with the intention of completely ignoring that warning. As for programming, there has never existed a piece of software that was built once and then left untouched. There will be changes before, during, and after developing the code. The code that was once correct is now wrong. The code you are writing today is also likely to be wrong. How will it be wrong? Will it be completely wrong or just slightly off-course? Will changes occur tomorrow or in some distant time so that only God knows how the code works? We can’t anticipate in what ways the code we are writing will need to change. This unknown subset of code that will require refactoring represents our error. Not knowing what code will end up being right or wrong in the future makes it very difficult to make programming decisions today. This is a type I and type II error problem.
Type I: Assuming Incorrect Code is Correct#
In this case we gamble that the cost of writing easily-changed code is greater than the cost of refactoring hard-to-change code. Crafting code that can be easily changed takes extra effort because we have to go out of our way to ensure it happens. Some examples of this type I assumption are when you use preexisting models because they are “close enough” to what is needed or alter existing functions to handle different use cases.
Inevitably, as requirements change, the code will need to be changed as well. Each iteration of changes adds more complexity. With additional complexity comes the feeling of dread. Changing the code becomes something that is avoided. This assumption - and its inevitable side-effects - can best be described by Yoda:
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
Type II: Assuming Correct Code Is Incorrect#
Although this path is initially more difficult, it is one instance in which assuming you are wrong sets you up to be right! You choose to assume that all of the code you are writing is going to require change at some point. This is the most realistic approach to writing software. The requirements will change. The scenario is not constant. Since this is your reality, making a type II assumption during the development process will allow you to properly prepare for that inevitable refactoring. Many thought leaders in our industry have been pointing us in this direction. For example Mary Poppendieck, author of Lean Software Development tells us that,
Almost everything we know about good architecture has to do with making software easy to change.
The presupposition of this quote is that software is always changing. So we as developers should design it for change from the start!
How do we make our code easy to change, though? It’s one thing to academically state this, but when fingers hit keyboards and projects are underway, good intentions are lost in the flurry of work. The best tools that we have to keep our code easy to change is to follow the SOLID principles.