Earlier this week I travelled to Newcastle to deliver a presentation on Technical Debt. The feedback from the audience was very positive and so I thought it was worth sharing the main points of my talk with you.
Technical Debt – a Definition or Two
Ward Cunningham defined technical debt as being analogous to financial debt. With financial debt you borrow money now in order to obtain some benefit that you could not otherwise obtain – the purchase of a car for example. In the future you are going to have to pay back the money you borrowed, along with some interest on the capital. Ward suggests that it is the same with technical debt. You borrow time now, in the form of taking engineering or architectural short cuts, in order to obtain some benefit that you could not otherwise obtain – meeting a project milestone for example. Just like with financial debt, in the future you are going to have to pay back the time you borrowed, along with some extra time (the interest) that is the cost of not doing the thing properly in the first instance.
I have taken the liberty of expanding this definition a little. Staying with the financial analogy, I further suggest that technical debt can be accrued if you do not take advantage of technical advancements and software components where possible. In much the same way, in financial terms, you can make a notional loss if you have your savings in an account that pays 2% interest, when you could have had it in an account that pays 5% interest.
Not All Debt is Bad
Of course, not all financial debt is bad. In fact, a certain about of financial debt is almost required to run a successful company. Used wisely, financial debt can be used to start companies. A company may borrow money in order to purchase raw materials, which they then make into widgets, which they sell for enough profit to pay off the original loan and purchase more raw goods. The same is undoubtedly true of technical debt. A company may borrow time in one iteration in order to hit an important milestone, and pay the debt off in the next iteration.
But Some is Deadly
Of course, no matter how well you think your financial debt is managed, there could always be something unexpected that comes along to mess it up for you. Witness the recent credit crunch, where banks demanded instant repayment of outstanding loans, forcing many companies to the wall. The same is true of technical debt, carry too much, or carry it for too long and something will come along and force your project to the wall.
A Safe Level of Technical Debt
That being the case, it is best if you have no technical debt in your projects, right? Okay, I know what you are thinking, having no technical debt is like having no bugs in your software, it’s something great to aim for but it’s not at all realistic, there are bugs in every system and there will be technical debt in every code base. Well that’s true, but here’s what I claim. I claim that if I provide you with an application and even although there are bugs in it, if the bugs are so hard to find that, even after months of use, you never hit them, then you’d be fair enough in saying that my application was bug free. Well I claim the same is true of technical debt. We know there will be technical debt in the code base, but if we drive it down to a level where it does not impact us, then to all intents and purposes, there is no technical debt. So what is that safe level? Well to be honest, it will depend on your project, but you’ll know what it is for yourself, as soon as you start to bump up against issues of technical debt then you are starting to “feel” that debt, then that is the time to start driving it down again.
Calculating Technical Debt
We need a system to put a financial value on the technical debt in our code base. We have to do this for two reasons. Firstly because you can’t drive down the amount of technical debt unless you have a way to quantify it, and secondly because you wont get sign off from your project manager to repay the debt unless you can show, in financial terms, how much money you are going to save in so doing. Why is this? Well, looking at things from a project management point of view, if you are going to spend an iteration driving down technical debt then what will happen is this. At the start of the iteration you may have 10 pieces of functionality coded in your application, at the end of the iteration you will still only have 10 pieces of functionality coded plus it will have cost you one development cycle (whatever that may cost your company). Now that is a tough sell for any project manager to make to the business. Of course if you can say something like, I’m going to spend one cycle – at a cost of £25K – but I’m going to remove £75k of technical debt from the code base, then that is a much easier sale to make.
To calculate technical debt is fairly straight forward. All you have to do is to sum the cost of each of the component parts of any fix required to drive down the technical debt. Things like, manpower costs, hardware costs and licencing costs. Not forgetting the hidden costs such as employer’s on costs and the cost to repair the damage to your brand of a late or shoddy release. There is a general formula and rate card in the presentation which you can use to get a feel for how to calculate the specific debt in your organisation.
Anti-Pattern: Not Invented Here
Just as there are patterns in good software design, there are anti-patterns in bad software design that can lead to the build up of technical debt. The first one we are going to look at is “Not Invented Here”. This anti-pattern is an example of the second class of technical debt we defined above. The class where savings against time were not made where possible by buying in a component to achieve non-core functionality in an application. The symptoms of this anti-pattern are that a team will insist on writing their own component – a charting control say – instead of buying one from a vendor, such as ourselves, for $250. The Technical Debt accrues from the cost of developing their own component plus the cost of maintaining it for the duration of the application lifecycle, a cost that far outweighs the purchase price of $250.
Anti-Pattern: Code That Plays Together Stays Together
This anti-pattern arises from an abuse of OO design principles. The symptoms are that an application has one or more “God” objects, objects which are stuffed full of properties and functions to the extent that no one developer on the team has a clear understanding of what they all do, and no one can define the responsibilities of the classes. This is an example of the first class of debt defined above, where time is borrowed in the form of an architectural shortcut (monolithic object models are easier to define than models where proper separation of concerns has taken place) but has to be paid back, with interest, in the form of the extra time it now takes to add new functionality to the model.
Metric: Decrease in Productivity
Being able to spot these anti-patterns is helpful, but it is also helpful to be able to use metrics to indicate that technical debt is building up in your project. One such metric is a decrease in productivity. If you graph items of functionality completed per iteration then you should see a variance from one iteration to another, after all not all pieces of functionality take equal time to complete and so some iterations will have more completed pieces than others. However the trend should be fairly constant across the iterations. If you see the trend declining this can indicate that there is technical debt in your codebase. The debt takes the form of code you have to “go around” in order to get things done. The more of it there is, the more of this code you have to write and so the less functionality you can get through per iteration.
Metric: Increase in Number of Tests Per Piece of Functionality
In the same way, if you graph number of tests versus pieces of functionality, again you will see a variance but the trend should be near constant. However, if you see rising tests/functionality then that too can be an indicator of technical debt. This is because that extra code you wrote in the example above has to be tested and so the number of tests rises.
Tools Can Help You Defeat Technical Debt
There are tools available which can help you combat technical debt. DevExpress has both a free tool and a paid for tool. The tools will help you both in analysing your code, to make you aware of potential technical debt and by helping you to refactor that code to eliminate the debt. Of course our competitors also sell tools in this area. Which is best? Well that’s not for me to say, you’ll just have to download, compare and decide! 