E-Book, Englisch, 258 Seiten
Managing Technical Debt
E-Book, Englisch, 258 Seiten
ISBN: 978-0-12-801646-6
Verlag: Elsevier Science & Techn.
Format: EPUB
Kopierschutz: Adobe DRM (»Systemvoraussetzungen)
Girish Suryanarayana is currently a Senior Research Scientist at Research and Technology Center, Siemens Technology and Services Pvt. Ltd. Bangalore, India. At Siemens, he is involved in providing architectural guidance to software development teams, pursuing research in topics related to software architecture and cloud computing, and conducting internal software design and architecture training. Girish is a member of the IEEE Software Advisory Board and is the General Chair for the IEEE Software Experts Summit 2014 conference. He actively contributes to software engineering conferences. In 2013, he was on the program committee for the Software Engineering In Practice (SEIP) track at the 35th International Conference on Software Engineering (ICSE). Girish received a PhD in Information and Computer Science from the University of California, Irvine, in 2007. His research interests include software architecture, design patterns, design smells, refactoring, cloud computing, and reputation-based trust management systems. He is an IEEE-certified Software Engineering Certified Instructor (SECI) and regularly conducts training for the IEEE SWEBOK Certificate Program (SCP) and IEEE Certified Software Development Associate (CSDA) programs. He has also helped contribute course material for the IEEE's SWEBOK Certificate Program (SCP). He is regularly invited by local universities to deliver guest lectures on software architecture and design topics. Additionally, he is the General Chair for IEEE SES (Software Expert Summit) 2014 which is being organized by IEEE Software.
Autoren/Hrsg.
Weitere Infos & Material
1;Front
Cover;1
2;Refactoring for
Software Design
Smells;4
3;Copyright;5
4;Dedication;6
5;Contents;8
6;Foreword by Grady Booch;10
7;Foreword by Dr. Stéphane Ducasse;12
8;Preface;14
8.1;WHAT IS THIS BOOK ABOUT?;14
8.2;WHAT DOES THIS BOOK COVER?;14
8.3;WHO SHOULD READ THIS BOOK?;15
8.4;WHAT ARE THE PREREQUISITES FOR READING THIS BOOK?;16
8.5;HOW TO READ THIS BOOK?;16
8.6;WHERE CAN I FIND MORE INFORMATION?;17
8.7;WHY DID WE WRITE THIS BOOK?;18
9;Acknowledgments;20
10;Chapter 1 - Technical Debt;22
10.1;1.1 WHAT IS TECHNICAL DEBT?;23
10.2;1.2 WHAT CONSTITUTES TECHNICAL DEBT?;23
10.3;1.3 WHAT IS THE IMPACT OF TECHNICAL DEBT?;25
10.4;1.4 WHAT CAUSES TECHNICAL DEBT?;27
10.5;1.5 HOW TO MANAGE TECHNICAL DEBT?;28
11;Chapter 2 - Design Smells;30
11.1;2.1 WHY CARE ABOUT SMELLS?;31
11.2;2.2 WHAT CAUSES SMELLS?;33
11.3;2.3 HOW TO ADDRESS SMELLS?;36
11.4;2.4 WHAT SMELLS ARE COVERED IN THIS BOOK?;36
11.5;2.5 A CLASSIFICATION OF DESIGN SMELLS;36
12;Chapter 3 - Abstraction Smells;42
12.1;3.1 MISSING ABSTRACTION;45
12.2;3.2 IMPERATIVE ABSTRACTION;50
12.3;3.3 INCOMPLETE ABSTRACTION;55
12.4;3.4 MULTIFACETED ABSTRACTION;61
12.5;3.5 UNNECESSARY ABSTRACTION;65
12.6;3.6 UNUTILIZED ABSTRACTION;70
12.7;3.7 DUPLICATE ABSTRACTION;75
13;Chapter 4 - Encapsulation Smells;82
13.1;4.1 DEFICIENT ENCAPSULATION;84
13.2;4.2 LEAKY ENCAPSULATION;93
13.3;4.3 MISSING ENCAPSULATION;99
13.4;4.4 UNEXPLOITED ENCAPSULATION;107
14;Chapter 5 - Modularization Smells;114
14.1;5.1 BROKEN MODULARIZATION;117
14.2;5.2 INSUFFICIENT MODULARIZATION;123
14.3;5.3 CYCLICALLY-DEPENDENT MODULARIZATION;129
14.4;5.4 HUB-LIKE MODULARIZATION;139
15;Chapter 6 - Hierarchy Smells;144
15.1;6.1 MISSING HIERARCHY;148
15.2;6.2 UNNECESSARY HIERARCHY;155
15.3;6.3 UNFACTORED HIERARCHY;161
15.4;6.4 WIDE HIERARCHY;171
15.5;6.5 SPECULATIVE HIERARCHY;175
15.6;6.6 DEEP HIERARCHY;178
15.7;6.7 REBELLIOUS HIERARCHY;184
15.8;6.8 BROKEN HIERARCHY;194
15.9;6.9 MULTIPATH HIERARCHY;203
15.10;6.10 CYCLIC HIERARCHY;208
16;Chapter 7 - The Smell Ecosystem;214
16.1;7.1 THE ROLE OF CONTEXT;214
16.2;7.2 INTERPLAY OF SMELLS;217
17;Chapter 8 - Repaying Technical Debt in Practice;224
17.1;8.1 THE TOOLS;224
17.2;8.2 THE PROCESS;227
17.3;8.3 THE PEOPLE;233
18;Appendix A - Software Design Principles;234
18.1;A.1 ABSTRACTION;234
18.2;A.2 ACYCLIC DEPENDENCIES PRINCIPLE;234
18.3;A.3 DON’T REPEAT YOURSELF PRINCIPLE;234
18.4;A.4 ENCAPSULATION;235
18.5;A.5 INFORMATION HIDING PRINCIPLE;235
18.6;A.6 KEEP IT SIMPLE SILLY;235
18.7;A.7 LISKOV’S SUBSTITUTION PRINCIPLE;235
18.8;A.8 HIERARCHY;236
18.9;A.9 MODULARIZATION;236
18.10;A.10 OPEN/CLOSE PRINCIPLE;236
18.11;A.11 SINGLE RESPONSIBILITY PRINCIPLE;236
18.12;A.12 VARIATION ENCAPSULATION PRINCIPLE;236
19;Appendix B - Tools for Repaying Technical Debt;238
20;Appendix C - Notations for Figures;244
21;Appendix D - Suggested Reading;246
21.1;D.1 ESSENTIALS;246
21.2;D.2 REFACTORING AND REENGINEERING;246
21.3;D.3 PATTERNS AND ANTI-PATTERNS;247
21.4;D.4 TECHNICAL DEBT;247
22;Bibliography;248
23;Index;252
Chapter 1 Technical Debt
Abstract
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. Keywords
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, [6] 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 [44]. 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...