Track Smells for Improved Maintainability

Lifecycle of smells

It is commonly understood that an excessive number of smells in a software system impair the quality of the software and makes the software hard to maintain and evolve. A lot about smells has been studied and written in last two decades. You may find a large collection of smells in the form of a taxonomy and the current knowledge (including definition, cause, effect, detection methods, and open research challenges) about smells in a literature survey paper.

Why track code smells?

In a recent post, Joost Visser (CTO of SIG) reported that only 1 in 3 software development teams put processes in place to control code quality. It is an unfortunate reality. However, more importantly, the detection and measurements are only the first steps. Even though a team detects smells and measure code quality, it is not enough. The team has to take a corrective action based on the measurement and detection results. The lack of any corrective action nullifies any benefit of putting together a code quality process.

Not all smells need to be refactored!!

When we write code, knowingly or unknowingly we introduce smells. We may detect some smells manually; however, typically we use tools to detect smells in our code. Undesirably, many times there is no action after smells are detected in a codebase. Other times, quality conscious software developers attempt to refactor some of the detected smells. Still, there are often a large number of detected smells that developers discard consciously. It happens when either the developers think that the tool has detected the smell wrongly or they consider it is infeasible to refactor the smell due to various reasons. For instance, a developer may find a smell infeasible to refactor when the smell has been detected in legacy code which she might not want to or even don’t have permission to change. Other reasons could be technical — there is no rational and effective way to refactor the smell without introducing new smells. Even further, sometimes developers think that the refactoring of the detected smell will bring minor improvement comparing to the effort required to refactor it.

Lifecycle of smells
Lifecycle of smells

The above context outlines that a smell could be treated in multiple ways based on its semantics and context. Many of the detected smells could be discarded but a significant fraction of them has to be refactored. If a developer took a call to refactor a smell in future, there must be an easy way to track whether it is indeed done.

How to track smells? Existing tools/frameworks?

However, how a developer can track all the identified smells? One painful way is to refer the smell detection tool and the output generated from it. Some tools may allow exporting the detected smells in some convenient format (say CSV). However, it is quite cumbersome and ineffective to work in an editor/IDE and refer the output of a smell detection tool. It only deters developers to ignore the detected smells. Isn’t it convenient for a developer if the identified smells are indicated within her IDE without creating a distraction and details could be accessed when needed?

One may say that they are tracking smells in technical debt tracking tools such as SonarQube. Despite its reasonable capabilities to inspect and monitor code quality in general, it is not an effective solution for tracking smells. First, by default, SonarQube do not detect a comprehensive maintainability smells specially at design and architecture granularities. Even if you are using a plug-in of SonarQube to detect smells, your smell tracking mechanism is not integrated with your development environment. It reduces the implementation of the smell tracking mechanism significantly.

Also, some may argue to use IDE extensions such as SonarLint. It is definitely a recommended extension; however, it is not offering you a detailed and comprehensive code smells detection. Hence, since it is not detecting smells, you cannot track them within the IDE using it.

Manage smells within Visual Studio using Designite

Designite is a software design quality assessment tool that analyzes C# code and detects a comprehensive set of architecture, design, and implementation smells. Additionally, it provides mechanisms such as detailed metrics analysis, Dependency Structure Matrix (DSM), trend analysis, and smell distribution maps. Designite offers an extension which can be installed in Visual Studio 2017.

Designite not only detects smells but also allow developers to track and manage them. Specifically, smell tagging and Action Hub features make it possible. All the detected design and implementation smells are shown within the Visual Studio IDE as orange glyphs with red rectangle next to a class (or method) declaration. Therefore, if a class suffers from a design smell, a smell-glyph will appear next to the class declaration; in the case of implementation smells, the glyph appears next to the method declaration. Such smell tagging motivates developers to take an action on the smells corresponding to the class/method. Smell tagging not only flags the source code elements with smells but also allows the user to quickly look at the smell details and more importantly change their status.

Smell tagging by Designite within Visual Studio
Smell tagging by Designite within Visual Studio

Corresponding to the life-cycle of a smell, Designite supports four smell status:

  • Identified: All the newly identified smells are tagged as Identified.
  • Refactor: A developer assigns this status when she thinks she should refactor the identified smell.
  • Wrong: A smell gets assigned to this status when the developer thinks that the tool has identified the smell wrongly.
  • Drop: There are cases when developers know that the smell exists but they cannot (or don’t want to) refactor it due to various reasons discussed above. In such cases, it is logical to assign the smell drop status.

A developer sees smell-glyphs only for smells that are tagged either as identified or refactor status. Smells tagged as drop or wrong are not shown by Designite within Visual Studio. Further, if a smell is assigned refactor status and the developer refactors it, then the associated smell-glyph will be removed when the project gets analyzed next time.

A bright orange color smell-glyph keeps prompting the developer to take action on the smell. It promotes the Boy Scout rule of continuous refactoring.

Finally, Action Hub provides a consolidated view of all the identified smells and offers a navigation mechanism for it. When a developer analyzes a project, Designite keeps the analysis report for later use by Action Hub. One may filter the smells based on various factors such as smell types (architecture, design, or implementation), smell status (identified, drop, wrong, or refactor), or smell location (such as project or namespace). One may also change the status of a smell from Action Hub.

Action Hub at work
Action Hub at work

To conclude, identifying smells is only the first step. We, as developers, have to take an appropriate action on the identified set of smells. Designite facilitates not only identification of a comprehensive set of smells but also offers tracking and managing smells effectively within Visual Studio. It makes the goal of improving maintainability of source code easier to achieve.