Should You Ship This Code Before Reducing Technical Debt?!

Technical debt is usually perceived as a measure of expediency. You borrow a little (time) with the intent of paying it back as soon as possible. To quote Ward Cunnigham:

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… I thought that rushing software out the door to get some experience with it was a good idea, but that of course, you would eventually go back and as you learned things about that software you would repay that loan by refactoring the program to reflect your experience as you acquired it.

As is often the case with financial debt, technical debt accrues with compound interest. Once it reaches a certain level (e.g. $1 per line of code) you stare at a difficult question:

Should I ship this code before reducing the accrued technical debt?!

The Figure below, taken from An Objective Measure of Code Quality by Mark Dixon, answers the question with respect to one important component of technical debt – cyclomatic complexity. Once complexity per source code file exceeds 74, the file is for most practical purposes guaranteed to contain errors. Some of the errors in such a file might be trivial. However, a 2007 study by Capers Jones indicates about a third of the errors found in released code are likely to be serious enough to stop an application from running or create erroneous outputs.

To answer the question cited above – Should You Ship This Software Before Reducing Technical Debt?! – examine both cost and risk for the number of error-prone files you are about to unleash:

The economics of defect removal clearly favor early defect removal over late defect removal. The cost of removal grows exponentially as function of time.

Brand risk should be first and foremost on your mind. If complexity figures higher than 74 per file are more of the norm than the exception, you are quite likely to tarnish your image due to poor quality.

If you decide to postpone the release date until the technical debt has been reduced, you can apply yourself to technical debt reduction in a biggest-bang-for-the-buck manner. The analysis of complexity can identify the hot spots in your code, giving you a de-facto roadmap you would be wise to follow.

Conversely, if you opt to ship the code without reducing technical debt, you might lose this degree of freedom to prioritize your “fix it” work. Customer situations and pressures might force you to attend to fixing modules that do not necessarily provide as much bang for the buck.

Postscript: Please note that the discussion in this post is strictly limited to intrinsic quality. It does not address at all extrinsic quality. In other words, reducing/eliminating technical debt does not guarantee that the customer will find the code valuable. I would suggest reading Beyond Scope, Schedule and Cost: Measuring Agile Performance in the Cutter Blog for a more detailed analysis of the distinction between the two.

[…] Managing “technical debt” has been an interesting conversation in some parts of the Agil…. Technical debt is a nice way of accounting for “things we should have done, but did not in the interest of releasing sooner.” […]

CC looks like it adds some value, but I’d guess that it’s not trivial to use since either you measure it on a subset of the code (and would probably need to build some sort of tool to trawl the parse tree of the compiler/interpreter), or (I think), it’s comparable to the halting problem when applied across a complete program + it’s set of possible inputs.

I am looking for any sort of objective measure of test coverage, since techniques like TDD are too reliant on the experience of the programmer for a project manager to trust them ;-)

CC, and other technical debt metrics like duplication, rule violation and coverage add a lot of value. I would actually go as far as stating that their on-going use to monitor the quality of the code is a pre-requisite for the long term success of continuous deployment.