Outdated belief #4: Technical debt results from poor architecture design
In the software community, there’s a general belief that software ages, just like humans — David Parnas is famous for this quote (among many other things). Our findings don’t confirm this. We’ve studied architecture technical debt as well as other types of technical debt for a decade and we’ve generated all kinds of results. One of our most surprising findings, resulting from a survey with hundreds of respondents, was that there seems to be no correlation between system age and technical debt.
Our hypothesis to explain this is that there always is technical debt but that the type of debt changes over time. Young systems often have technical debt as the architects operate under a lot of uncertainty about the optimal way of achieving the desired functionality and consequently make decisions that in hindsight turn out to be suboptimal. For established systems, there often is debt due to the scaling required from the system. This causes functionally correct design decisions to be unable to satisfy non-functional requirements. Finally, for older systems, we’re more frequently dealing with technology obsolescence where components need to be replaced with newer alternatives and where, for instance, the architectural style needs to be replaced to meet newer insights.
As an example of the latter, many embedded systems used a monolithic software architecture where components can directly call each other and sometimes even access a global variable space. This allows for high computational efficiency but results in low development efficiency when scaling. Many organizations building embedded systems are now exploring a transition to containerized components or subsystems and message bus-based communication. The latter sacrifices some computational efficiency, but less than one would expect, and allows for much higher development efficiency as well as for updating of individual components rather than the entire image.
Especially those that originate from mechanical and electronics disciplines, where the cost of changes after the start of production often is prohibitively high, tend to consider technical debt, especially for young systems, to be an indication that the architects did a poor job designing the architecture. As the saying goes, hindsight is 20–20, and it’s easy, even for those with limited software expertise, to claim that it should have been obvious that certain decisions were the wrong ones.
This claim is of course incorrect for at least two reasons. First, at the time the decision was made, there typically was much less information available than there is now. Second, what’s important today from a business perspective is typically different from what was considered important when the decision was made. Many tend to forget that the business evolves continuously as well.
In this context, I frequently use the BAPO model to show the close connection between business and business strategy and the architecture and technology choices. The primary dependency should be that business drives architecture, architecture drives the process, ways of working and tools, and that these drive the organizational setup.
In practice, however, it’s the architects who are predicting where the business is going and proactively adjusting the architecture to optimally support the future business. As such, they set the real business strategy for the company, which is why close interaction between business strategists and system and software architects is so important. Preferably, the constant evolution of architecture occurs proactively, rather than reactively, so that the architecture is always optimal for what the company needs at any point in time.
This also means that I’m highly skeptical of new platform and architecture initiatives. Rather than letting the existing architecture ‘rot’ until it’s no longer usable and then kicking off the development of a new architecture, it’s much better to continuously invest some percentage of your R&D resources towards architecture refactoring. This has two main advantages. First, you never suffer through a period where the architecture is poorly supporting the business because it’s outdated. Second, it avoids the high risks associated with new platforms — the investment is often quite high and reaching feature parity with the existing platform is time consuming and expensive.
Identified technical debt in your architecture is a positive, rather than a negative, aspect of your software R&D. If you wouldn’t continuously invest in addressing technical debt, your architecture would rapidly start to age and become outdated. That aging isn’t the consequence of bad decisions but rather an inherent property of a continuously evolving business. Different from humans, software doesn’t have to age but can be perpetually young and optimal, as long as you prioritize technical debt management sufficiently. Imagine never having to build a new platform, with all the associated risks and costs, because your current one is fit for purpose at all times.