Our build came up recently in a planning session at work. It's a standard big ball of mud, with hidden knowledge all over. It's frail, inconsistent and unhelpful, it's complicated to work with and almost nobody ever gets their local build past "good enough for now" to "working well".
This has been an issue for a while and it hadn't been given the proper attention to be improved. Every change had been reactionary to various needs and it had changed hands so many times that any beliefs or design philosophies it had were long lost.
When asked how much effort was required to fix it, the answer was "You can't."
While I wasn't originally, I'm now a fan of the term "technical debt". It brings with it a handful of related concepts and terminology that make discussions easier. In this case, compound interest, and bankruptcy.
It all starts when you first make a big investment; probably your first release. Fixing up the last minute bugs before release, cutting corners in the name of getting to market, making "just for now" trade offs going against technical soundness. Each of these things add to your technical debt. There's nothing wrong with this, it's expected.
But then your debt starts adding up pretty quickly:
- Changes in business needs for the system
- Changes in company direction
- Changes in team composition, staff sizing
- Cutting corners on in-code documentation
- Industry changes
- Not keeping up with underlying frameworks
- Not following proper language techniques
- Quick security patches
- Scalability needs
- Blindly meeting code metrics
- Over reliance on under-skilled developers
- Not testing on up to date integration points (databases, operating systems, etc)
- Quick and dirty bug fixes
- Minor improvements
Lots of ways.
As time passes, they lose some of the context. Surrounding code begins to change, bug fixes are introduced, and other developers build on what was written instead of what was intended. More time passes and other code is refactored, team members come and go or the pattern gets copied elsewhere in your code base.
Every organization has different priorities, goals and principles. As such, calculating how or where to pay for your technical debt varies wildly. Of course, the rule of thumb is "Pay off debt that is costing you the most." There are a handful of ways to do this:
- Research and Analysis: Work to establish what business functionality should be delivered next then prototype any areas that are known hot spots or developers do not have experience with. With the gained experience determine if the code in question is deeply in debt or if it can afford the new feature.
- Raise Rates: When asked to estimate a new feature in an area that has high technical debt, focus on estimates which include needed code revitalization. Just as it's the business duty to plan features customers want, it's a developer's responsibility manage risk ensuring it's done technically correct.
- Foreign Exchange: Exchange the technical currency into salaries as an incentive to keep developers. Many larger, non-technical firms follow this route. It's like buying carbon credits; the debt is still there, but developers are rewarded for tolerating it.
- Creative Accounting: Buffer estimates and deliverables with needed cleanups. Once someone knows an area of code well, perform small improvements under other ledgers.
- Get a Second Job: One of the most dire methods is to band together and either work nights or through lunchtime to make the needed improvements.
- Bankruptcy: Sometimes there's honestly no other choice other than to start over.