First of all, make sure you read my previous technical debt management posts (how technical debt can be both good and bad) – this post is designed to address the issues described therein.
What can be done to prevent negative technical debt and ensure you are in control of positive technical debt? How do you prevent it becoming a problem?
The simple answer is that you can’t. All systems will have some planned and unplanned technical debt. Software development is a complex, fast moving business and developers are only human. Decisions and technology choices made in the best of faith will turn out to be wrong.
However there are some methods that can be used to minimize the risk and impact of technical debt. Here are some necessary elements of technical debt management:
- Good system architecture
- Abstract systems, so that switching out technologies or areas of the system can be done with minimal impact
- Robust system management
- Enough testing (automated or manual) and documentation to enable low risk re-engineering if needed
- Shared responsibilities so that the system is not too dependent on individuals
- Technical debt management
- Awareness of areas of technical debt within the system and of the longer term impact of the compromises or decisions you are making now
Paying off debt
Well, there are three ways and I will do my best to stretch the financial metaphor one last time to illustrate them…
Ongoing small payments
Make a commitment that with every feature introduced an area of technical debt will also be addressed. Make technical debt everyone’s ongoing problem.
Lump Sum Payment
Take everyone out of feature production for a set period and resolve the main areas of technical debt. Make technical debt everyone’s problem for a short time.
Dedicated payment plan
Create a dedicated technical debt management team who do nothing but resolve technical debt issues and run this alongside the development program. Create some people who have technical debt management as their only problem.
MVP vs Future Proofing
One of the buzz words at the moment is MVP (Minimum Viable Product) – the concept of only building the bare minimum that is needed to deliver the current requirement – like the XP concept of YAGNI (You Aren’t Gonna Need It).
Back in the mists of time when I first started developing, it was all about future proofing – building the framework into your software to allow for future changes to be introduced in a simpler way.
So which approach is right?
I often come across developers advocating elements of future proofing. The reasons advocating such are:
- Future proofing builds a system based on solid foundations
- Cutting costs by not doing this piece of work now will lead to increased costs later
- The major impact of certain future events can be mitigated with a small amount of effort now
However, for me these advantages are outweighed by the advantages of the MVP approach:
- The business will see benefit from the work much sooner
- Future proofing is spending money now in case you need to spend it in future – the vast majority of future proofing efforts end up going unused
- Future proofing can be made obsolete by non-technical issues
- Changing business requirements
- New technologies – how often have we spent days coding round an issue that then was included in the next release of the language?
- Failure of third parties your system depends on
That said, I would still advocate good development practices as a way of minimizing the impact of change later on. Good practices like separation of concerns, loosely coupled objects, modular design, reasonable levels of abstraction, dependency injection etc. are all the building blocks that will enable you to create a system that is well placed for change.
Reduced functionality is no excuse for bad code.