There are various kinds of tools available to help you identify design smells and candidates for refactoring, quantify their significance, visualize the accumulated technical debt, and perform refactoring to repay debt. Let us discuss the following kinds of tools in this article:
• Comprehension tools
• Critique tools, code clone detectors, and metric tools
• Technical debt quantification and visualization tools
• Refactoring tools
An important prerequisite for proposing and making proper changes in the code base of any real-world software system is to understand the internal structure of the code. Large software systems (the ones that span millions of lines of code) are difficult to comprehend due to their size and complexity. To address this, you can employ comprehension tools to understand the internal structure of the code (through visual aids such as control structure visualization, data flow analysis, call-sequence analysis, and inheritance graph).
Critique tools, clone detectors, and metric tools
Critique tools analyze the software and report problems in the form of violations of predefined rules. Depending on the granularity of the smells they report, they can be classified as:
• Architectural critique tools that report architectural violations
• Design critique tools that report design smells
• Code analysis tools that identify potential bugs (aka “bug patterns”) at source code level
The presence of code clones indicate the possibility of smells such as Duplicate Abstraction and Unfactored Hierarchy. It is, therefore, important to detect code clones so that they can be addressed. In this context, code clone detectors can be used to analyze source code and identify code clones.
Metric tools analyze the code or design and report the results in the form of numeric values. These results then have to be analyzed to garner insights on design quality. Let us consider the example of Weighted Methods per Class (WMC), an object-oriented metric, which is a summation of Cyclomatic complexity of the methods in that class. By looking at the average values for WMC, a designer can get an idea of the level of complexity of the classes in his design. Further, by checking the reported WMC value against a fixed threshold value (say 50), he can detect instances of Insufficient Modularization smell.
Technical debt quantification and visualization tools
Given the significance of technical debt, it is important to be able to measure it. A prerequisite for measuring something is to be able to quantify it. In this context, technical debt is very difficult to quantify accurately. There are two main reasons for this. First, there is no clear consensus on the factors that contribute to technical debt. Second, there is no standard way to measure these factors. It is pertinent to note that there are some recent attempts that try to quantify technical debt; however, these approaches consider only a few factors which limits the usefulness of these approaches.
Related article: “Limitations of Technical Debt Quantification: Do you Rely on these Numbers?” published in InfoQ by Ganesh and Tushar.
Broadly, refactoring tools can be classified into the following two categories:
• Tools that detect refactoring candidates—These tools analyze the source code and identify not only the entity or entities that need to be refactored but also the potential refactoring steps that can be applied. However, note that these tools are still in a nascent phase of development.
• Tools that perform a refactoring—These tools can be employed to perform the required refactoring in the source code once the refactoring candidates have been identified. There are a few popular IDEs (Integrated Development Environments) that provide some automated support for refactoring; however, their support is limited to executing simple refactoring steps.
Applying tools in practice
It is important to consider the following practical aspects while using these tools in real-world projects.
• Violations or suggestions generated by critique and refactoring identification tools should be treated only as indications. These must be carefully analyzed manually by looking at the context (recall the importance of context that we discussed in the previous chapter) to eliminate false positives.
• As of this writing, refactoring tools are still maturing. For instance, there are IDEs that support carrying out refactoring tasks such as “extract class” refactoring, but they do not execute the task flawlessly i.e., they require moving of methods manually and leave broken code throughout the code base. Further, existing refactoring tools do not support refactoring complex smells such as Hub-like Modularization automatically. Hence, in practice, you may need to carry out refactoring tasks manually without any tool support.
• Selection of tools should be carefully performed depending on the project needs and organizational context. For instance, a few years back, I purchased a UML analysis tool to detect smells. However, this tool did not work with the UML diagrams that were created using Rational Rose and Enterprise Architect tools due to XMI (XML Metadata Interchange) compatibility issues. Hence, it is important to evaluate a commercial tool before purchasing it.
(Source: “Refactoring for Software Design Smells: Managing Technical Debt”, Girish Suryanarayana, Ganesh Samarthyam, Tushar Sharma, ISBN – 978-0128013977, Morgan Kaufmann/Elsevier, 2014. URL: http://amzn.com/0128013974)