Technical Debt

If you've been in software for any period of time, you encounter the idea of Technical Debt. It has been expounded upon by a number of luminaries and included in many software development books and blogs. ACCU has a nice write-up. It has been discussed on Ward C's wiki. Tim Ottinger tried to explain why pay-down doesn't happen. Steve McConnel chews the idea thoroughly. Technical debt has been likened to pollution.

We've not met a programmer who didn't believe that Technical Debt exists or that it is not significant. It is certain (or at least felt certainly) that ill-conceived or ill-formed code will impair the developers of any software system.

Well-designed code exhibits a deep and profound simplicity. When code has cleverness and magic in it, it tends to be complex and that complexity decays in the face of future changes. Well-designed code is code that follows the SOLID design principles (check out the audio version or the in-depth articles at Object Mentor). Simplicity and careful design don't exist as an academic study. Simplicity and careful design lead to a more fluid development process. Technical debt leads to a very rocky, uneven development process where very small changes in very bad areas become impossible to estimate. Even those changes that are not slow to write may end up bouncing around in QA for days, weeks, or even months. Any foray into bad code may cause delivery dates to be missed.

Bad code and poor design: that's what we call technical debt. This is not what Ward originally meant. He was referring to code written well to an incomplete understanding. As the word is used these days, it is to describe poor design and messy code. This is a shame, but here we use the term in the common sense, not as Ward intended.

I think there may be confusion in the way the word "quality" is used. If your definition includes opulence (gold-plating), self-indulgent implementation, needless future-proofing, complexity, wars over formatting, or man years of back-end testing with emergency rework, then one might be better off without it. If, on the other hand, your definition of quality is simplicity and well-crafted design then quality is essential and it makes no sense to argue against it.

Technical debt is drag, but quality and simplicity are thrust.

Once one finds that his team is suffering from technical debt what must be done? There are three choices:

Do nothing... allow it to accumulate and strangle productivity.

Pay it down by investing development dollars in cleaning the code.

Declare bankruptcy. Abandon the code and start over.

The bankruptcy option is a dire decision indeed. As mentioned on the AgileOtter blog article:

Doing nothing is an option frequently taken, but once the code impairs proper software development, one finds that avoiding ugly areas of code spreads the ugliness. Instead of making a fix where it belongs in the ugly code, a fix is made in all the places where the code is called. This creates duplication, which increases maintenance points, which increases the likelihood that you will get incomplete fixes in the future and which increases the ugliness in the caller code. This code eventually becomes indebted and the ugliness spreads from there as well.

The reasonable person will not take on debt he cannot afford. If the reasonable person takes on debt willingly, he does so with a clear plan for paying it. What kind of a person would borrow with no intention to pay? Such a person would be a fool or a crook.

So the big question is what you are going to do about your technical debt, and do you (as evidenced by your actions) understand and believe that code quality matters?

The most disturbing things about technical debt are that some lack (or have lost) the ability to see it when they're knee-deep in it, and others feel that it is a necessary condition of software development. This is more common in non-pairing, siloed development shops. Tim recommends pairing and breaking down silos to help get more eyes on the code.