Technical debt comes in various varieties

Ward Cunningham originally coined the term Technical Debt and described it at OOPSLA 1992

“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… 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.”

In this, Ward was not referring to poor programming practices, but to choices made based on the immediate needs of the time, but which had since been found to be at odds with future needs. An example of this might be a scheduling system that supports recurring events based on Gregorian calendar constructs when the situation also requires other basis such as a Lunar calendar. The concept of technical debt, and the techniques of paying down that debt, allow us to proceed with implementation of a naive or straightforward system knowing that as new requirements come to light, we can refactor to accommodate them. If we’ve built our scheduling system to have a dependency on the Gregorian calendar, we can refactor that to introduce a construct that better fits our needs, e.g. a Scheduling calendar, of which the Gregorian calendar is just one type.

I’m going to call this domain debt.

It has become popular in recent years to refer to “code smells” (a term apparently coined by Kent Beck) as technical debt. Code smells are things about the code that may not prevent it from working correctly, but that don’t “seem right” by the heuristics of an experienced programmer. These issues may span a wide variety of issues, from a method name that seems too general to give a clear understanding of what the method does, to a overly long method that does many things at many levels of abstraction. Some of these smells are stronger than others. Robert C. “Uncle Bob” Martin has identified some Principles of Object Oriented Development which are violated by some code smells. There are other “laws” of object oriented development, such as the Law of Demeter, which are generally good practice but perhaps not completely universal.

Inattention to code smells leads to a different type of technical debt. This one is based on a naive vision of implementation rather than a naive vision of the domain. It’s my experience that this debt mounts more rapidly. Taking on technical debt in terms of the domain or requirements may be analogous to taking on an automobile load so that we have reliable transportation that allows us to access gainful employment and further our goals. Taking on technical debt in terms of implementation is more analogous to incurring debt for expenses that may not be aligned with our future well-being. A marginal case would be similar to eating out at restaurants and paying with a credit card. While we need sustenance, if we spend more on it than we can afford to immediately pay, we reduce our ability to pay for necessities in the future. Sometimes it might be reasonable if we know the situation is going to change at a particular time, but often people get crushed by debt that grows unchecked in this fashion. Sometimes there are more significant acquisitions of debt such as taking a home equity loan to finance a vacation at an expensive resort. This is surely a recipe for future trouble.

I’m going to call this implementation debt.

A third category of problem that is often termed “technical debt” in the current vernacular is code that doesn’t work correctly. It may work for some cases, but miss some boundary conditions and either give incorrect answers or blow up spectacularly. I would call this a “defect” rather than a “debt.” There’s no doubt that, in most cases, such defects are related to technical debt of the second kind, implementation debt.

In the words of C. A. R. Hoare:

“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies.”

Most forms of implementation debt obscure the purpose of code, forcing us to deal directly with the details of implementation. The goal should be to write code that clearly states both its intent and design. To do this, we must purge it of duplicated functionality and enhance its expressiveness. Note that these are the middle two elements of Kent Beck’s four rules of simple design.

There was a time when it was generally accepted that the expression of the design was in one place, and the code merely followed the design that was expressed. Such a strategy has generally been found wanting. Such a separate design is not executable, and therefore cannot be tested to ensure it has the properties we seek in the system. Even when that separate design is excellent, there is no easy mechanism to ensure that the code follows it.

Fortunately, it has been shown that it’s possible to work from the other end. It’s quite possible to express a design adequately in the code, and use separate design artifacts to explain particular points or as an aid to conversation. To do this, we must purge our code of virtually all implementation debt, so that the design is clearly visible. Then we must keep the design debt at bay, so that our design reflects our current understanding of the problem domain—at least as far as we’ve implemented.

Notes:

  1. When asked about this passage, Ward told me, “I regret using the word ‘rewrite’. We did not use the word refactoring in 1992. I coined the term ‘consolidation’ later in the paper to describe the process that now goes by the term refactoring. I never rewrote more than a few dozen lines at a time.”
  2. Martin Fowler has a nice article classifying types of technical debt. I don’t think I’d ever read that before writing this one.

3 Replies to “Technical debt comes in various varieties”

  1. I like the idea of adding an adjective to the term technical debt. It makes it more descriptive, and teams can make better decisions when they understand the reasoning behind them.
    I agree with the term ‘defect’ as well. My usual stance is “Defects are a symptom of technical debt”. I think it is a stronger statement than ‘related to’. Also, thanks for the link to Martin Fowler’s blog post. I hadn’t read it for a long time and it was a good reminder.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.