Refactoring: Guided by Design Principles, Driven by Technical Debt

When one of our friends came to know about the book on Refactoring for Design Smells, he was curious and asked – “there are many books on refactoring so why should someone take a look at your book? In fact, I can perform various refactorings such as ‘extract method’ or ‘encapsulate field’ with a single click in my IDE – so why should I care about your book?”

Refactoring has come a long way from Opdyke’s thesis way back in 1992 which described refactoring as “behavior preserving transformations” [2]. Today, software developers use refactoring as a weapon against increasing complexity within their software system. There are various books, tools, and other resources available to aid the developers. Popular IDEs such as Eclipse, Visual Studio, and IntelliJ IDEA support automated refactoring. So, why another book on refactoring? Let us understand it by taking a deeper look at the concept.

Consider well-known smells such as “primitive obsession”, “data clumps”, and “data classes”. Why are they considered smells? When we use primitive types such as integer values, floating-point numbers, and strings for representing entities such as ISBN numbers and ZIP code, we are violating the fundamental principle of abstraction. Specifically, primitive obsession leads to code that extracts parts of a large number or string throughout the code base and uses the information wherever required. When we “pass around” clumps of data together (e.g., color values) or create classes that serve as “holders of data” (e.g., customer details), we are violating the principle of abstraction. Similarly, we violate the principle of encapsulation when data and algorithms that were supposed to be encapsulated get exposed through the class interface. Smells such as cyclic-dependencies and hub-like classes violate modularization principle. When the inheritance hierarchy is too wide or deep, it indicates the violation of the principle of hierarchy.

Perceiving smells as violation of design principles naturally guides us through the refactoring process. For example, when we view “primitive obsession” as violation of abstraction, the natural refactoring is to apply the principle of abstraction and create an abstraction. Similarly, hub-like classes violate the principle of modularization that naturally guides us towards a design with reduced coupling.

With this comes the insight that forms the core of our book: “When we view every smell as a violation of one or more underlying design principle(s), we understand how that smell occurred; but perhaps more importantly, it naturally points us towards a potential refactoring approach for that smell.”

The missing link in existing books and literature is to show how design principles can be applied in practice for creating high-quality software. Design principles are very important for developers and architects, as Craig Larman observes: “The critical design tool for software development is a mind well educated in design principles” [3]. Our book fills this important gap by illustrating how we can view smells and refactoring from the perspective of design principles.

Simon Sinek in his excellent TED talk [4] said: “it’s those who start with ‘why’ that have the ability to inspire those around them or find others who inspire them.” During software development, large organizations and their teams typically have access to various tools to detect smells and refactor them. They know “how” to refactor; however, they don’t often refactor; it is probably because “why” aspect is not understood with appropriate importance.

“Technical Debt” metaphor answers the question “why software teams must perform refactoring”. Ward Cunningham coined the term “Technical Debt” by comparing financial debt to the debt incurred by taking shortcuts in software projects [5]. When we take a loan, we incur debt. So long as we keep paying the installments, the created debt is fine and does not create problems. However, if we fail to pay the installments, we need to pay penalty charges. If we keep missing payments, the debt accumulates and makes it even more difficult to repay the debt. In an extreme case, we have to declare bankruptcy.

We observed that in real-world projects, taking shortcuts and avoiding refactoring leads to accumulating large technical debt over time. There are times when the technical debt gets overweight that it sinks the entire project (known as “technical bankruptcy”). Given that refactoring is the primary means to repay technical debt, this metaphor provides the “why” for refactoring. In our book we look at the concept of smells and refactoring in the context of technical debt, thus answering not only “how” but also “why” to refactor.

We also observed that software engineers working in real-world projects “know” about principles, but they often sorely lack knowledge and experience on how to apply them effectively in practice. Borrowing a phrase from the healthcare domain “a good doctor is one who knows the medicines but a great doctor is one who knows the disease”, our approach is grounded on the understanding the disease in the form of smells. When engineers view software design from the perspective of smells as violation of underlying design principles, they get a better understanding of how to apply principles in practice to create high quality designs.

It’s not all; there is more to the book:

– The book contains a comprehensive catalog of 25 structural design smells that contribute to technical debt in software projects. The design smells are presented using a detailed template consisting of smell name, description, rationale, potential causes, examples, suggested refactoring, impacted quality attributes, aliases, and practical considerations.

– It includes illustrative examples that showcase the poor design practices underlying a smell and the problems that result.

– The book covers pragmatic techniques for refactoring design smells to manage technical debt and to create and maintain high-quality software in practice.

– It presents insightful anecdotes and case studies drawn from the trenches of real-world projects that not only brings out causes and consequences of the smells but also decisions taken under the given context to mitigate the risks posed by the consequences.

To summarize: Our objective for writing this book was to provide a framework for understanding how smells occur as a violation of design principles and how they can be refactored so that technical debt can be kept under control. We hope that this core message reaches you through this book.

[This article is written with Girish Suryanarayana and Tushar Sharma and it appeared first in Elsevier’s scitechconnect blog].

References:

1. G. Suryanarayana, G. Samarthyam and T. Sharma, Refactoring for Software Design Smells: Managing Technical Debt, Morgan Kaufmann/Elsevier, 2014.

2. W. F. Opdyke, Refactoring Object-oriented Frameworks (PhD thesis), University of Illinois at Urbana-Champaign, 1992.

3. C. Larman, Applying UML and Patterns – An Introduction to Object-Oriented Analysis and Design and Iterative Development, New Jersey: Prentice Hall, 2005.

4. S. Sinek, “How great leaders inspire action,” [Online]. Available at: http://www.ted.com/talks/simon_sinek_how_great_leaders_inspire_action?language=en. [Accessed 15 September 2015].

5. W. Cunningham, “The WyCash Portfolio Management System,” 1992. [Online]. Available at: http://c2.com/doc/oopsla92.html. [Accessed 15 September 2015].

Leave a Reply

Your email address will not be published. Required fields are marked *