The tenants of good software design suggest businesses seek to create minimal viable products. In other words, develop the most important core features that allow you to deliver a product, and no more. You can always come back and add on to the product at a later date, but time to market is more important.
There is an inherent problem with the approach – it is not that we have cut corners and sacrificed quality to deliver our software, because we have made conscious decisions to only build what we absolutely need right now (to be successful).
The problem is incrementally designed software components can eventually feel “cobbled together” and become difficult and time-consuming to maintain.
Let’s say you’re writing an application. In the beginning, there isn’t a need for user permissions – everyone can do everything. At some point, you start having the need for permissions. One user needs to view content and another users should not be able to view the same content.
Right now, we just need something simple for 2 users – we do not need to design an entire system to manage user permissions. Doing so is over-engineering and will unnecessarily delay our project.
In our next version, we find a reason to add another user permission, and another, and another. Eventually, we have a series of small changes that (when considered individually) are easy to maintain; however, when looked at holistically, are in fact disparate. Your application has become a sloppy, wibbly-wobbly mess They are becoming sloppy and should be refactored into a simplified, reusable, and more maintainable permission system.
The next time we go to add a permission, we have a choice – take 2 hours to add the single permission (and add to the complexity), or take 2 days to refactor and make the system more maintainable. The trade-off in the refactored solution is significantly reducing the time to add new permissions in the future, at the cost of an additional 22 hours right now…and with each decision to not refactoring the solution, we add to the eventual cost.
This is technical debt – measuring the difference between a system’s optimal state (a “perfectly” refactored solution) and its current state (the sloppy, “cobbled together” mess it is today).
The Trouble with Technical Debt
The trouble with technical debt is that business owners have a difficulty understanding the consequences of not paying down the debt – perhaps because developers have a difficulty communicating the risks in a meaningful and effective business-value-driven way.
All software has some degree of technical debt – and it’s often difficult to measure the amount of debt unless your team knows where the software has been and what your solution needs to do tomorrow.
What Can You Do?
Most businesses ignore it. Why? Because it takes too much time, it’s painful, and costs too much. You could also retire .
But seriously, there are some things we can do from a practical standpoint. One thing is re-write the entire app – that should always be a possibility, but can be expensive. Also, what guarantees do you have that your current development and business team won’t make the same choices during the re-write?
Another thing you can do is identify areas of technical debt within your application – these are areas that make your developers groan when they’re asked to change them.
After you’ve found these areas, pay down your debt – give developers “creative” or “exploratory” time to prove-out a new approach, or just eliminate the debt.