We assume that less design effort allows producing features faster, in the short term. Less design effort generally means less abstraction, and tighter coupling, in order to produce working code faster.
But we tend to overlook the fact that it slows future modifications, even of unrelated features, because of tight coupling. We usually call this fact « technical debt », the term was first coined by Ward Cunningham. A better name was suggested by Steeve Freeman: unhedged call option.
Financial debt vs. Unhedged call option
Financial debt is predictable. You know how much you get, and how much you will pay back. A debt could be useful from a business perspective. A cash boost at the right time can create a major competitive advantage.
An unhedged call option also comes from the financial world, and is a really risky operation because it has unlimited downside. The buyer pays a premium to decide later if he wants to buy. The seller collects the premium, and will have to sell if the buyer decides to buy. It is not predictable for the seller.
Transpose to software, the difference with the concept of debt is the predictability in the amount of work required to fulfill our engagement.
When we write crappy code (tightly coupled and without tests), we collect the premium: we immediately get benefit from the new feature.
Every time this kind of tradeoff is required, we should ask who is asking for this, why, and who is going to pay it. Fun fact: those who ask for it (and directly benefit from it) are not often those who will pay it.
The sales team for example may ask for a quick hack because the customers « really, really need it yesterday ». But it may be paid by the production team, because next time the customer will want something, we still have to produce it quickly, without any regression. That’s where we will support more pressure, and may do some overtime.
In the end everyone will be impacted, because more pressure means more bugs, more regressions, and finally unhappy users. No company can survive unhappy users forever.
But what‘s good design?
We all try to do our best, but some of us lack knowledge and/or feedback. Plus, good design is contextual.
But regarding of our context, good designs have common points. It allows to think clearly about our software, and to evolve it easily. It allows to know where we should add/modify/fix a feature. The evolution-ability gives us an option on how to add/modify/fix this feature.
Decoupling is then required because we need to think about small parts in isolation, without side effects. This kind of good design allows producing predictable software: robust, resilient and without regression when it evolves.
If we use shortcuts, and couple our code in order to rush it into production, we must be aware there will be an unpredictable amount of time to pay to get back into a predictable state.
It does not mean we should never do it, but we all have to understand this trade-off before asking for a “debt”.
What about speaking of predictability?
The more shortcuts you take, the less predictable your software will be. If you pay more for well design software, you get the opposite effect.
Unfortunately it is hard to judge, as we usually think we design software well. A good way to know if we are on good track is to rely on how predictable is the software we produce. Are the customers happy? The production team? The sales team? Do we have very few regressions? Do we produce features at a regular speed?
If not, we should consider investing more on design and refactoring, before entering into a vicious circle of unmanageable software.
The technical debt Myth.
That’s why the comparison with a financial debt is sub-optimal. Money debt is predictable, whereas software debt is not. Unhedged call option is a better name, but still comes from the financial world.
Maybe we should stop financial comparison and speak of predictability instead. I find it is a better description of the consequences of shortcuts in the design.
Thanks Brian Gibson, always here to help me to improve!