The technical debt in software: a present issue with future implications
The overriding aim when launching the software design stage is the provision of solutions to the issues of concern to the product’s users. Yet the way in which the software is developed will have an impact upon its ability to adapt to fresh requirements and, accordingly, the generation of future versions. The key to the creation of sustainable software over the long term calls on developers to understand how the system is coded and be capable of expanding, modifying or updating it. This gives rise to two concepts: the legacy code and the technical debt.
A succinct definition of a legacy code is one that someone has created and that subsequently needs to be maintained by other developers. This in itself should not be a problem, provided that the code complies with certain rules so that any third party that has to work with it can understand it and adapt it to their needs without the major drawback of the time this takes.
Legacy code is clearly a major issue that may trouble a software engineer, but their true concern when maintaining or developing pre-existing software involves its technical debt.
What is a technical debt?
In 1992, Ward Cunningham, a programmer and co-author of the Agile Manifesto for software development, coined the phrase technical debt. Cunningham wanted to shed light on the importance that refactoring (i.e., the regular adjustment of the code) has for software. Only in this way is it possible to stop software generating more debt over time due to its growing operating and structural deficiencies. Technical debt arises when a solution is designed with a short-term perspective, or by excessively economizing on resources, whereby it may indeed respond to current needs, yet not have a code structure that is legible for future developers, thereby requiring a significant maintenance effort. Developing software according to this premise constitutes a huge burden in the long term, as its development first requires addressing those parts that were not optimized or which were resolved in a clumsy manner.
Hence the reason it is essential to use software engineering that not only caters to the initial requirements established but also does so in a sustainable manner. All software should evolve, and some of these modifications will affect the part that has already been composed. It is therefore important that when the moment arrives, the person responsible for introducing these changes will be able to use what they have in the most straightforward way possible because the original designer has already made allowance for such a contingency. If this is not the case, a patch will be required in the future to resolve a specific issue, and this will place a burden on the system. Addressing the creation of systems from this perspective calls for discipline and a greater investment of time, but it will be worth it in the long run.
It is vital to consider the different scenarios in which the software will be required to operate, seeking to avoid any limitations on the specific fulfillment of users’ requirements.
When tackling the creation of a new software system, it is important to ensure that, over time and as the product evolves and grows, the technical debt will be reduced to zero. This renders it vital to consider the different scenarios in which the software will be required to operate, seeking to avoid any limitations on the specific fulfilment of users’ requirements.
We may be catering for a function in a narrowly defined environment that has previously been described, but what will probably happen in this case is that if this system’s ambit of application changes, it will be unable to operate in this new environment. For example, if we resolve a connectivity problem between a machine and the workshop by designing a system that links that specific model of machine to the operating system on the computer being used in the workshop, what will happen when we replace the computer or the model of machine? And when we include more machines or more computers? This will probably involve changing the software, requiring more development work…whereby the software engineer will be facing a constant dilemma, between prioritising the efforts required for preparing systems to adapt to any future contingency and the costs these incur.
The aim is to consider those issues than can foreseeably be addressed in most cases. In the long run, this will drastically reduce the time spent on improving functions or introducing new ones.
The matter in hand here is whether the technical debt (which is measured in terms of effort, and therefore the product’s financial costs) may tend towards zero, and the answer is that it does. The complication arises when there is no legacy code (i.e., the amount of code used for the software passed down when continuing to operate with the same system). It is fairly common for code to have to change as all nature of improvements arise. Yet if the solution, and therefore the code, is designed to be sustainable, these changes will be relatively straightforward and no major efforts will be required to keep the technical debt to a minimum. The investment in time and money will match the success of the product or systems that we maintain and develop. Nevertheless, the debt grows every time the code is changed in a non-sustainable manner.
A software engineer’s overriding concern should be the care and sustainability of the source code
The key is to spend the time needed not only to consider the future requirements that this software will have to meet, but also to develop the selfsame software ensuring its technical integrity, whereby it will always appear to have been designed and developed by the same person. The conceptual integrity of all parts of the system should behave in a similar way to ensure each user has the same experience regardless of whether they use the oldest or the most recent parts. Given that the system is evolving and continuously adapting, this will restrict the new developments’ possible solutions to technical requirements that may be applied both to the new code and to the original parts of the system.
This means that a software engineer’s overriding concern should be the care and sustainability of the source code. The application of best practices to software engineering will ensure the future is easier to understand and address for a third party. If this task is undertaken in a due and proper manner, legacy code will never pose a problem, as we will have reduced its technical debt to a minimum.
This does not mean, however, that the code will last for ever within a system, as the time is likely to come when we have to start again almost from scratch. It is vital to try to delay that moment as far as possible. A longer life-cycle will mean a more successful product for stakeholders, users, and software engineers.