Technical debt is the debt that accrues when developers knowingly or unknowingly make wrong or nonoptimal design decisions. Technical debt is akin to financial debt. Allowing a small debt to occur is acceptable provided it is paid soon enough; not paying the debt for a longer period invites bigger troubles. Similarly, in a software project, technical debt needs to be repaid regularly to avoid its accumulation. Large technical debt significantly degrades the quality of the software system and affects the productivity of the development team. In extreme cases, when the accumulated technical debt becomes so huge that it cannot be paid off anymore, the product has to be abandoned. This chapter emphasizes the importance of the concept of technical debt, the factors that contribute to it, and its impact on software projects.
Causes of technical debt; Design debt; Project failures; Refactoring; Technical bankruptcy; Technical debt
The first and most fundamental question to ask before commencing on this journey of refactoring for design smells is: What are design smells and why is it important to refactor the design to remove the smells?
Fred Brooks, in his book The Mythical Man Month
describes how the inherent properties of software (i.e., complexity, conformity, changeability, and invisibility) make its design an “essential” difficulty. Good design practices are fundamental requisites to address this difficulty. One such practice is that a software designer should be aware of and address design smells
that can manifest as a result of design decisions. This is the topic we cover in this book.
So, what are design smells?
Design smells are certain structures in the design that indicate violation of fundamental design principles and negatively impact design quality.
In other words, a design smell indicates a potential problem in the design structure. The medical domain provides a good analogy for our work on smells. The symptoms of a patient can be likened to a “smell,” and the underlying disease can be likened to the concrete “design problem.”
This analogy can be extended to the process of diagnosis as well. For instance, a physician analyzes the symptoms, determines the disease at the root of the symptoms, and then suggests a treatment. Similarly, a designer has to analyze the smells found in a design, determine the problem(s) underlying the smells, and then identify the required refactoring to address the problem(s).
Having introduced design smells, let us ask why it is important to refactor1
the design to remove the smells.
The answer to this question lies in technical debt—a term that has been receiving considerable attention from the software development community for the past few years. It is important to acquire an overview of technical debt so that software developers can understand the far-reaching implications of the design decisions that they make on a daily basis in their projects. Therefore, we devote the discussion in the rest of this chapter to technical debt.
1.1. What is Technical Debt?
Technical debt is the debt that accrues when you knowingly or unknowingly make wrong or non-optimal design decisions.
Technical debt is a metaphor coined by Ward Cunningham in a 1992 report 
. Technical debt is analogous to financial debt. When a person takes a loan (or uses his credit card), he incurs debt. If he regularly pays the installments (or the credit card bill) then the created debt is repaid and does not create further problems. However, if the person does not pay his installment (or bill), a penalty in the form of interest is applicable and it mounts every time he misses the payment. In case the person is not able to pay the installments (or bill) for a long time, the accrued interest can make the total debt so ominously large that the person may have to declare bankruptcy.
Along the same lines, when a software developer opts for a quick fix rather than a proper well-designed solution, he introduces technical debt. It is okay if the developer pays back the debt on time. However, if the developer chooses not to pay or forgets about the debt created, the accrued interest on the technical debt piles up, just like financial debt, increasing the overall technical debt. The debt keeps increasing over time with each change to the software; thus, the later the developer pays off the debt, the more expensive it is to pay off. If the debt is not paid at all, then eventually the pile-up becomes so huge that it becomes immensely difficult to change the software. In extreme cases, the accumulated technical debt is so huge that it cannot be paid off anymore and the product has to be abandoned. Such a situation is called technical bankruptcy.
1.2. What Constitutes Technical Debt?
There are multiple sources of technical debt (Figure 1.1
). Some of the well-known dimensions of technical debt include (with examples):
• Code debt: Static analysis tool violations and inconsistent coding style.
• Design debt: Design smells and violations of design rules.
• Test debt: Lack of tests, inadequate test coverage, and improper test design.
• Documentation debt: No documentation for important concerns, poor documentation, and outdated documentation.
In this book, we are primarily concerned with the design aspects of technical debt, i.e., design debt. In other words, when we refer to technical debt in this book, we imply design debt.
To better understand design debt, let us take the case of a medium-sized organization that develops software products. To be able to compete with other organizations in the market, this organization obviously wants to get newer products on the market faster and at reduced costs. But how does this impact its software development process? As one can imagine, its software developers are expected to implement features faster. In such a case, the developers may not have the opportunity or time to properly assess the impact of their design decisions. As a result, over time, such a collection of individual localized design decisions starts to degrade the structural quality of the software products, thereby contributing to the accumulation of design debt.
FIGURE 1.1 Dimensions of technical debt.
If such a product were to be developed just once and then no longer maintained, the structural quality would not matter. However, most products are in the market for a long time period and therefore have an extended development and maintenance life cycle. In such a case, the poor structural quality of the software will significantly increase the effort and time required to understand and maintain the software. This will eventually hurt the organization’s interests. Thus, it is extremely important for organizations to monitor and address the structural quality of the software. The work that needs to be invested in the future to address the current structural quality issues in the software is design debt.
An interesting question in the context of what constitutes technical debt is whether defects/bugs are a part of this debt. Some argue that defects (at least some of them) originate due to technical debt, thus are part of technical debt. There are others who support this viewpoint and argue that if managers decide to release a software version despite it having many known yet-to-be-fixed defects, these defects are a part of technical debt that has been incurred.
However, there are others in the community who argue that defects do not constitute technical debt. They argue that the main difference between defects and technical debt is that defects are visible to the users while technical debt is largely invisible. We support this stance. In our experience, defects are rarely ignored by the organization and receive much attention from the development teams. On the other hand, issues leading to technical debt are mostly invisible and tend to receive little or no attention from the development teams. Why does this happen?
This happens because defects directly impact external quality attributes of the software that are directly visible to the end users. Technical debt, on the other hand, impacts internal quality of the software system, and is not directly perceivable by the end users of the software. Organizations value their end users and cannot afford to lose them; thus, defects get the utmost attention while issues related to “invisible” technical debt are usually deferred or ignored. Thus, from a practical viewpoint, it is better to leave defects out of the umbrella of technical debt, so that they can be dealt with separately; otherwise, one would fix defects and mistakenly think that technical debt has been addressed.
1.3. What is the Impact of Technical Debt?
Why is it important for a software practitioner to be aware of technical debt and keep it under control? To understand this, let us first understand the components of technical debt. Technical debt is a result of the principal (the original hack or shortcut), and the accumulated interest incurred when the principal is not fixed. The interest component is compounding in nature; the more you ignore it or postpone it, the bigger the debt becomes over time. Thus, it is the interest component that makes technical debt a significant problem.
Why is the interest...