Sunday, November 11, 2007

Managing technical debts

I have recently read a bunch of articles and discussions about a common pattern in software projects development: the technical debts.

Controlling the chaos: in all living structures the entropy invariably tends to develop ; one key role of the team in charge of a software project is to lower this entropy before the code becomes unmaintainable.
Indeed, a too common outcome of an overwhelming code entropy is what can easily be assimilated to a "death by suffocation": the projects abort because the teams end up spending 100% of its time and efforts fixing bugs, whereas one or two years before everybody was feeling in control and confident for a great and happy future.

Why is this so often happening? How should we fight it?
I will just try and gather here the few ideas I have selected from my readings and experience.

First key - becoming aware of the debt

The technical debts come too often unnoticed. They form sneaky underground diseases, relatively harmless at their beginning, and yet possibly mortal in the long run.
To keep the system healthy, a responsible team must learn to realize when they authorize a technical debt to get in.

Second key - measuring the usefulness of the debt

The "debt" metaphor hasnt' been chosen by accident. By contracting a technical debt, you borrow Quality in order to buy Time: for delivering faster, you decide to weaken the structure of your shiny new building. You will eventually pay it back later, using time you assume you will have in the future.

And as with financial debts, there are interests! The first, fixed-rate, interest is the maintenance work ; another one, more vicious, is the"magnet effect" provoked by this quality hole: with time, its existence serves as a implicit justification for using it elsewhere (as deeply explained by the "broken window theory"), making a future fix much more difficult to perform.

However, the technical debt is not necessarily always a bad thing. For business strategic reasons, a team can decide to allow it:
 - it may be wise to be ready to pay more in the future if time-to-market is critical
 - if the software is close to the end of its life in production, it makes sense to forget about technical debts that you will never have to pay back.

Third Key - reassessing regularly the debt

Technical debts are part of most projects lifetimes ; since they bring with them a cost that often grows over time, I think that a responsible team should ideally keep track of all existing debts, and build a system that calls their existence back to mind when appropriate (for instance when the next developped features impact the code closed to the debt)

Agile methodologies advocate this continous assessment, as well as the usage of a very powerful arm against the emergence of technical debts, i.e. merciless refactorings.

Fourth key - consider the debt as a risk factor for the future team velocity

Though best suited to fight this software development disease, I have learned the hard way that XP can also be endangered by it. Indeed, it is sometimes necessary to run into large refactorings for the health of the application, and this can badly impact the team velocity. The rate for adding new features varies a lot from one iteration to the next, and the team loses confidence in its ability to reliably estimate stories.
If we don't take this reality into account and communicate badly about it to the management or the stakeholders, it also becomes very awkward to continue to tell them that Agile is really that agile...
A core response is certainly the "merciless refactoring" of XP, but from experience, I find it very hard, even for an experienced team, to avoid the emergence of all technical debts that will ask for large refactorings.
That's why another, more pragmatic response, could be to lower the forecast team velocity sufficiently in advance before an actual large refactoring becomes mandatory to the developement of a feature... and define and plan a smooth and incremental strategy to conduct the refactoring.

Do you think of better/complementary ways of dealing with technical debts?

If you want to read more about it, I suggest to start with Steve Mc Connell blog post, that explores further the analogy with financial debts and categorizes the technical debts into different types.