After having presented some prioritization considerations and approaches in the previous chapter, as the next step, it is time to address the topic of technical debt repayment. First of all, this chapter discusses the importance of continuous repayment. Secondly, it also provides a description of the various ways of retiring technical debt.
3.6.1
Continuous repayment
Just like monetary debt is not paid back all at once, technical debt should be paid back step by step as well. In addition, it cannot be emphasized enough that some of the technical debt does not even need to be paid back at all. Furthermore, as Buschmann [8] pointed it out, paying down technical debt has its own risks as well. Given that many types of debt repayment actions can affect software in production, value can be destroyed as well and not just created. Therefore, it is essential to use minimally invasive solutions.
Development teams can do repayments at micro and macro levels as well. On the one hand, micro level repayments should be continuously done by developers working on the code base. Thus, repayment certainly results to be less burdensome to them. While on the other hand, macro level technical
debt (typically architectural debt) needs to be addressed in recurring clean- up releases.
3.6.2
Means of repayment
Li et al. [25] also addressed the topic of technical debt repayment and along- side with many other authors, also mentioned refactoring, rewriting, automa- tion and fixing of regressions as possible ways of paying technical debt down. However, since all of these are rather focused on the already existing code base, this chapter introduces a few more approaches that can address other types of debt as well, such as the creation of tests, skill management and the revision of communication practices.
3.6.2.1 Refactoring
Refactoring is probably the most commonly known and applied way of tech- nical debt repayment. During the process, the already existing source code is changed in a way that the functionality of the component remains completely intact. However, since the process has no visible outcomes, managers tend to be rather reluctant to the idea of refactoring. It is considered a waste of time, especially if it is carried out with the goal of avoiding future problems that may or may not arise. As a consequence, most of the time people say: “If it’s not broken, don’t fix it”
In general, senior developers are the ones who propose and advocate refac- toring, since they see it as an investment. In contrast, junior developers tend to lack the experience and necessary vision to suggest changes of this type. However, regardless of experience level, refactoring is always preferred to be carried out in a progressive fashion. In other words, Uncle Bob’s boy scout rule needs to be the main driver of everyday work of developers: “Always leave the code that you are editing better than you found it.”
3.6.2.2 Rewriting from the ground up
Sometimes the accumulated technical debt reaches extremely high levels in a project. In these cases, instead of fixing all the issues, it is better to abandon the existing source code and re-implement everything again from the ground up. Self-evidently, the fewer lines the affected code contains, the more acceptable this approach is by less technical people as well. On a related note, this repayment method requires rather precise estimates both for fixing the existing technical debt and for the effort of re-implementation.
3.6.2.3 Automation
Manually done processes tend to be repetitive and therefore, incredibly error- prone. Therefore, as indicated in Appendix A, process debt can be partially remedied by automating processes. Some typical examples would be the introduction of Continuous Integration (CI) and Continuous Delivery (CD) solutions.
3.6.2.4 Fixigin regressions
The need for this kind of repayment is the most visible to everybody, since it has to do with broken functionality. Although Li et al. [25] mentioned resolving bugs in general — including defects — as means of repayment, it is a statement that is difficult to agree with in this methodology, since software defects are not considered to be technical debt. However, unnoticed regres- sions, which are introduced when other bugs are fixed, do form a relevant class of technical debt. Therefore, resolving those issues is also one of the ways of reducing debt.
3.6.2.5 Writing tests
Self-evidently, testing-related debt (see Appendix A) can only be paid back by writing (more) tests. Since software has various requirements, several different types of tests exist. Corresponding to the type of requirements, tests can be divided into two groups: functional (e.g., unit, integration, regression) testing and non-functional (e.g., performance, security, usability) testing.
A good option to consider here is adopting Test-Driven Development (TDD) to eliminate the problem of insufficient testing at its roots: during development time. As part of this software development process, a set of tests are written before the actual code is implemented, which quite self-evidently, initially have to fail. Therefore, the goal is to create an implementation that enables the tests to pass. This helps to avoid the “I can see that my code works, there is no need for tests. I know I wrote it well.” kind of thoughts that some developers might have.
3.6.2.6 Educating people
As described in Appendix A, there is a type of debt that is related to human resources of projects. One way to repay this debt is by recruiting profession- als with just the right skills from the beginning. However, due to different constraint (e.g., urgent need for a developer), this is usually impossible to do in practice. The only viable options are either teaching the necessary
skills to employees or simply finding ways that facilitate their learning on their own. In addition, it is also worth encouraging employees to broaden their professional horizons and not to get stuck doing the same kind of work during years.
3.6.2.7 Revising communication practices
This repayment method aims to address the topic of process and require- ment debt, by checking whether the right communication practices are used. For instance, it might be the case that the preferred way of communication is via emails, in order to make sure that managers can monitor the flow of activities by receiving carbon copies of every email. However, many times, more direct, instant messages are more powerful tools. Therefore, the recom- mendation is to use live communication (e.g., face-to-face meetings, calls and instant messages) for everyday activities and save more permanent means of information exchange (e.g., emails) for making announcements and commu- nicating important decisions. The next chapter provides further details on the communication of technical debt itself.