The true status and health of a large software project is surprisingly difficult to sense, and worse to measure. One of the best ways to understand this is to think about debt. Although not measured in dollars, software projects certainly accumulate debt over time. This is debt that you will have to pay someday — or continue paying interest to delay the day of reckoning — if the project is successful.
How many of these apply to your project?
7 sources of technical debt
- Undiscovered bugs, failing tests, and open bugs in your database
- Missing test automation (unit, feature, scenario, or system)
- Missing build and deployment automation
- Scenarios with incomplete user experiences
- Code that’s too difficult to understand
- Code that’s too difficult to extend
- Code that’s isolated in branches
The insidious thing is your project can hit all its milestones and even make it the whole way to shipping — with any amount of these debts lurking in the code.
In a next post, we’ll look at 7 matching strategies for measuring and tackling technical debt, so you can empower your teams to systematically manage it in a lean fashion.
Alan Dean | 14-May-07 at 6:10 am | Permalink
Martin Fowler’s bliki entry on technical debt can be seen at http://www.martinfowler.com/bl.....lDebt.html
Bernie | 14-May-07 at 8:59 am | Permalink
Thanks, Alan! Great background.
M. Hassan Raza | 15-May-07 at 9:17 am | Permalink
You know onething I have an issue for old and new code, the last project i was managing, this project was three years old, has code from Java to VB6 to ASP3 to ASP.NET 1.1 to C# 1.1, Now we migrated from .NET 1.1 to .NET 2, but what about the old code, tested code, yes obviously would have a lot of bugs but this code base is like 70% of the system. Currently system is waiting for a lot of new features and changes but the old code is there as well.
It just seems impossible to migrate because of a huge cost.
This code also misses test automation.
It just seems a bit stupid to even think of going there but we still have a lot of technical debt as you just pointed out.
Any Comments!
Bernie | 15-May-07 at 10:20 am | Permalink
It’s tough when you have a large body of older, well-tested code that’s got a lot of these debts. That kind of code is almost always fragile. Your team might hate it, be afraid to touch it. But know that you can’t pay this debt off all at once (many projects try this, and enter a quagmire of no return). It’s best done in a lean fashion — refactoring in small batches, stepwise, over time.
Good starting advice with legacy software (given how risk-prone it is to re-write it en masse) is “if it ain’t broke, don’t fix it”. So what do you do? Define a threshold — probably a high standard — for accepting change. When the “interest” you’re paying or nagging bugs you’re suffering from in the old code fall below the threshold, you resist the temptation to touch it — no major new features, just live with the problems.
We’re hard-nosed about this, because the temptation for developers is going to be “this is crap, I have to rewrite the whole thing”. We have to resist this to a point.
But when the threshold is passed (e.g. a major new feature that has to get done, or there are structural bugs that just need fixed), don’t get yourself deeper in debt by patching these changes against unmaintainable code. It’s then that you should start putting rewrite work on your backlog, piece by piece — rewriting the old code in the smallest batches possible to get the changes you need. “Done” for these new, refactored pieces means hitting the new, higher quality bar: invest the effort now to make them highest possible quality & the fewest possible debts.
This step-wise refactoring will require a lot of scaffolding to and extra glue keep your house together while it’s being remodeled. But it’s worth it when the alternative is a risky, big-batch rewrite.
Unfortunately, there isn’t a silver bullet to get out from under a huge burden of debt. It takes time, patience, and hard work. But done thoughtfully and carefully, you can succeed where many others have failed.
coreyl | 15-May-07 at 12:34 pm | Permalink
One thing you can do is planned refactoring. Set aside some defined percentage of your available engineering capacity for design improvement. This is part of the “O” in a Design for Six Sigma DMADOV (or IDOV or CDOV, whatever) process, so you don’t even have to think of it as remedial. Quality improvements come from tightening up the specifications for features you’re already shipped as well as introducing new ones. Also, reengineering is an investment in future productivity. There are ample business reasons to spend some effort on design optimization, as long as it is managed and value-driven.
rob | 15-May-07 at 12:43 pm | Permalink
#6 is particularly insidious: sometimes it’s not that the code is not extensible, but that the use of the code has extended past what the architecture was originally intended for. Win 3.1 was never architected to be a pre-emptive 32 bit operating system. (especially considering it’s an extention of the cooperative application environment of win 2.x). Win95 & successors did a decent job, but you could tell that they were taking extensions to the limit.
When you build an architecture, you build also a set of assumptions (hopefully, consciously) about the environment it will be used. Over time, it’s easy to forget these assumptions, or forget to validate the new uses against those assumptions. I guess this gets classified as future debts due to assumptions.
A second, unrelated issue comes to mind too: there are few people who can hold in their head all the scenarios and subtleties that the kernel memory manager or scheduler has to consider (and bugs introduced may not surface for years, literally). It’s not that the code is difficult to understand, but that it’s used in so many ways it takes a particular talent to understand them all. I wonder how this fits into the 7? Maybe it’s just a variation on #5. Maybe it’s more a cashflow thing – as long as you have your brilliant developer (technical income generator), you’re fine. As soon as they’re gone, you incur massive debt fast.
kyaw kyaw naing | 14-Sep-08 at 9:32 am | Permalink
I guess lack of self-discipline is first cause of technical debt.
We all have this problem. To help us save from ourselves, we need structure and proceses.