Sunday, 18 August 2013

Technical Debt and Legacy Code

It's time to ban the phrase "technical debt". It's a metaphor that's been stretched to mean too many things, from hand waving usages to make teams "go faster" to being a catch-all excuse for developers to write terrible code. I'd like to challenge you to avoid saying "technical debt" and instead try to define the actual problem. By stating the problem concretely, you're already closer to the solution.

Let's go right back to the beginning. Ward Cunningham introduced the metaphor of technical debt at OOPSLA 92 in "The Wycash Portfolio Management System" experience report. Let's look at what he says:

Another, more serious pitfall is the failure to consolidate. Although immature code may work fine and be completely acceptable to the customer, excess quantities will make a program unmasterable, leading to extreme specialization of programmers and finally an inflexible product. Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite. Objects make the cost of this transaction tolerable. The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object- oriented or otherwise.

What Ward is saying here is that the build up of technical debt starts when you ship something with an incomplete understanding of the problem. It's the acknowledgement that we never ship the right thing first time. This isn't news to anyone! No matter what the customer says, the first time they get the new feature they want something slightly different. Technical debt starts to occur when you don't reflect that difference back to the underlying code.

The original definition of technical debt is nothing to do with quality of the code alone, it's simply an acknowledgement that once your code no longer models the problem, you're in trouble. Things aren't going to get better until you acknowledge that and fix things. I'm willing to bet that this definition of technical debt isn't the one you use.

Unfortunately, when I hear the term technical debt it's usually in the context of moaning about legacy code.

Most of us know what legacy code is. It's really hard to work with. It's difficult to like (though some might say there is Joy in Legacy Code), and progress is slow. Saying it's full of technical debt is almost certainly true, but it's not very helpful. You need to define that debt in meaningful ways so you can do something about it (or explain your woes concretely to the rest of the team so you can make time to tackle it as a team). In this context, technical debt is nothing but a lazy phrase to stop you concretely defining what the problems really are. As Bob Martin says "A Mess is Not Technical Debt" article.

Ever wonder why it's so hard to convince your boss to have time to tackle technical debt? You're fighting the wrong battle. You're describing the problem in terms of your domain, not the problem domain. What happens if you're not allowed to say "technical debt"? Now you're forced to describe the problem in concrete terms. How is the code mismatched against the customer requirements? Which one is the more compelling case to make to your boss?

So stop being lazy; define problems in concrete terms and don't use the dreaded phrase "technical debt".