This was originally posted on my blog: https://unremarqued.wordpress.com/2020/04/09/aesop-vs-technical-debt/
If you’ve been involved in the development of software, you may have heard one or more cranky developers use "Technical Debt" as an argument as to why an urgently requested feature will require much more time than "management" expected it to.
For non-developers at the receiving end of these complaints, the spectre of technical debt can be a frustrating one. As a result, moralistic judgements can be made against developers. Aesop's fable of The Ant and The Grasshopper comes to mind: If only developers were more like busy ants storing up time (efficiency) for the impending feature request winter they would not have to beg for more time today like the indolent Grasshopper.
There are many scholarly works out there on the topic of Technical Debt but for our purposes let's define Technical Debt as any extra or unnecessary work that must be done to meaningfully add a new feature to an end-user's software. Whilst this article focuses mostly on the developers, Technical Debt is not limited to the code itself, it extends to the whole of the effort it takes to get code to a state where it can be used and evaluated (i.e. “deployed”). For instance, an overly manual toolchain where automation has been neglected can impede the addition of a new feature to software as much as poorly written code.
For many who have never written software, there is a “set and forget” fallacy that is applied to the development of a new software feature. Focus is generally on the coding of a new feature not the maintenance of said feature. It is in the maintenance of code (or building on previously written code) that technical debt originates. As Martin Fowler and others have pointed out: It’s not just bad code that makes up technical debt, it’s bad code and repeated touching or working with said code that gives rise to technical debt.
In the terms of the fable, writing a brand new feature can feel like summer. Resources are abundant and the world seems full of possibilities! However, extending or maintaining existing functionality happens in the winter when time and even grace is in short supply and one is forced to work with what one developed in the summer. This is where Technical Debt is experienced.
Addressing the Technical Debt problem solely through the lens of the Ant and the Grasshopper makes the question of avoiding Technical Debt effectively a moral one: in theory, if developers were just more experienced, more efficient, more assiduous, or just overall more virtuous then Technical Debt could be eliminated because we'd all be well prepared for winter. We just need to teach our Developers to be more Ant-like and less Grasshopper-like.
However, I would argue from my experience as a developer that the dominant culture is already overwhelmingly to be like our friend the Ant and "code things the right way". Few developers WANT to incur technical debt; in fact most developers strive to NOT be "that developer" who wrote the sloppy and bug-laden code that his peers malign.
Whilst higher morals and strength of character might eliminate some Technical Debt when applied to truly lazy developers, just being an industrious developer doesn't seem to completely solve the problem of technical debt. This is because Aesop's fable only tells half of the story.
Continuing to run with the context of Aesop's fable, every feature request posed to a developer presents them with two choices with regard to its development:
- Act like the Ant: Do they write it “the right way” using more time now to implement the feature?
- Act like the Grasshopper: Do they write it in a more slapdash way, using less time now but increasing (potential) maintenance cost in the future?
But this is where Aesop's fable starts to let us down. In the real software development world, sometimes it can pay to be a Grasshopper and sometimes Ants lose big.
So if the currency of Technical Debt is time, we can classify the Developer's Dilemma in quadrants:
When we limit our understanding of Technical Debt to a moral question, we wind up focusing on the "Prudent Development" quadrant whilst trying to avoid the "Technical Debt" quadrant. In reality, unlike Aesop's fable, sometimes winter is never visited upon a feature, meaning that we have both a new quadrant for which to strive ("Rapid Development") and a new one to avoid ("Wasted Effort").
The heart of the Dilemma for developers is that they can't control the when and how of both Summer and Winter, they can only control whether they act like the Ant or the Grasshopper in the face of a feature request; and both approaches lead can lead to big wins or big losses.
Ant-inclined developers can work hard to make a feature as robust as anything only to have that feature cut and wind up with a net loss of time; like the ant in the fable working hard for a winter that never comes (Wasted Effort). What's worse, developers intending to be good Ants can prepare for the wrong winter by fortifying the wrong parts of a feature, and still wind up begging for time like winter Grasshoppers (Technical Debt).
Meanwhile, Grasshoppers can win big by leveraging the fact that Technical Debt only emerges when "Set and Forget" is actually a fallacy. If a feature is never revisited then Technical Debt can never emerge. Thus the kind of scenarios that play out in the Rapid Development quadrant are kind of a sort of "prescient bets" such as:
- Implementing a feature quickly but then having the feature cut due to new business knowledge
- Implementing a crufty but stable feature (as Martin Fowler calls it) that never needs to be built upon
So what can be learned by introducing Aesop's classic into the discussion of Technical Debt? The key is that Technical Debt is not (predominantly) a moral issue. Whilst some technical debt does emerge due to inexperience or real laziness, the vast majority of technical debt emerges due to our inherent inability to know the future.
In other words, Aesop's fable cannot fully capture the factors behind technical debt since the fable makes two assumptions that aren't true about software development:
- That the right way to "store for the winter" (implement a feature to incur unnecessary effort later on) is known a priori.
- That winter always comes
With these assumptions removed the rightmost quadrants of the grid above open up and the fable gives way to the Developer's Dilemma. With this comes the counterintuitive conclusion that sometimes developers would do well to act more like the (oft misunderstood) Grasshopper.
The astute among us would also see the uncomfortable corollary that until we can accurately predict the future (or invent time travel) we will never completely eradicate Technical Debt. Instead we need to learn how to continually manage it.
Whether you identify as a Grasshopper or an Ant, take heart. Once we remove morality from of the discussion of Technical Debt we can understand the problem for what it truly is. It's then that all parties, developer and non-developer alike, can hone in on the proper set of techniques to minimise it, namely those techniques that are employed to deal with uncertainty. To that end, in future posts I hope to highlight how both the practice of DevOps and wise old engineers are uniquely positioned to combat technical debt (but perhaps in unexpected ways)