Code smells are a common occurrence today. Know what they are, the types, the levels, how to fix them, and what code smells detection tools you should use today.
What are Code Smells?
Blob class. Brain repository. Loose class names. Fat repository. Laborious repository method. These are all types of code smells. Despite the perhaps funny names, the presence of code smells is a serious topic.
Anyone with experience in software development knows that code smells can seriously slow down software releases. A number of previous studies of all shapes and sizes have been published – from the diffuseness of code smells by Palomba et al presented at the international symposium on empirical software engineering; to the evolution of code smells in object-oriented systems; to assessing the impact of code smells with historical information (Lozano et al). Many an international symposium or international conference has been dedicated to the impact of code smells. It is safe to say that the presence of code smells and the effects of code smells can slow down activity and be a detriment to any software solution.
The term “code smells” was first popularized by Kent Beck , the creator of extreme programming, in the mid ’90s and later popularized in Martin Fowler’s book, Refactoring. Simply defined, code smells are any violation of fundamental design principles that decrease the overall quality of the code. Code smells generally indicate a deeper problem. They are not bugs or errors in that they are not officially incorrect code and they do not prevent the implementation of the program, though code smells can certainly add to the chance of bugs and failures down the line. Alternatively, code smells indicate a poor design that has the ability to slow down development and can be an indicator of factors which may contribute to technical debt. Deciding exactly what a code smell is can differ between programming languages, developers, and methodology.
By using code smell detection tools and subjecting the code to short and controlled refactoring sessions, you can go beyond the initial impact of code smells and discover the deeper problem within the software. Code smells can often be vital to discovering when to refactor and which refactoring techniques to use.
In 2015, an empirical study by Tufano et al, analyzing both automated and manual code commits to exhibit bad smells, found that there was only anecdotal evidence for how, when or why such smells occur. However, again according to the empirical study, Tufano, Palomba, and their associates state that common wisdom suggests that the high-pressure to deliver features and prioritizing time-to-market over code comprehensibility can lead to bad code and bad smells. Most developers today don’t need to reference previous studies to know that this is often the case, especially as they must handle projects with larger sizes and complex attributes.
Coding has come a long way and is not just about writing lines of code to get output. Today, if teams and businesses want to survive, they have to optimize their software so that it can perform at the highest level for the longest amount of time. Code and design smells indicate deeper problems, such as classes with data but no behavior. However, by being aware of these code smells and using code smell detection tools like Sider, these stinky problems can become easy to sniff out.
What are Some Common Types of Smells?
Originally, only 22 code smell types were identified, but code smell reference lists have certainly grown since then. Bad smells can differ between projects and developers, but there are certain code smell instances that occur more than others, and the impact of code smells can be serious. Keeping a catalog of code smells may be helpful, but here are some examples of code smell types:
These are lines of code and classes that have grown so large and unruly that you can no longer work with them. These smells evolve over time and can include large classes, data clumps, spaghetti code, and other long method code smells (A popular study by Khomh F and others was presented at the 15th European conference regarding spaghetti code).
Object Orientation Abusers
These include the poor application of object-oriented programming principles. Examples include switch statements, temporary fields, or alternative classes with different interfaces.
The code smell instances in this group can make your software development much more complicated (and, therefore, expensive) because the presence of code smells here indicates that you will need to make multiple changes across your code. Divergent change, parallel inheritance hierarchies, and shotgun surgery are all change preventers.
As the name suggests, dispensables are any activity in your code that is unneeded. Once eliminated, your code will be much cleaner and easier to understand. Lazy class, comments, and duplicate code are all dispensable.
These add to excessive coupling between classes. Examples are feature envy, inappropriate intimacy, and middleman code smells.
Some software systems are prone to specific types of smells. For example, according to the study by Aniche et al presented at the international conference on software maintenance and looking at code smells and the Model-View-Controller pattern, there are six MVC-smelly classes. These MVC-smelly classes include brain repository, fat repository, laborious repository method, and others. These MVC-smelly classes were shown to have a huge impact on change- and defect-proneness of classes, a severe problem for these developers. These MVC smells are often created when the code artifact is created and not as a result of evolution activities performed on the code artifact, according to the study.
What are Code Smells Levels?
Similar to the different type of code smells, bad smells, from across the different types, occur at different levels, such as:
Application Level Smells
Smells at this level include duplicate code (a dispensable in which similar lines of code appear in more than one location), shotgun surgery (a change preventer where one change means altering several different classes), and contrived complexity (in which a bloated design pattern is used when a simpler design pattern could be used).
Class Level Smells
There are many different types of code smells that can occur at the class level. Some are:
- Large Class or God Class or Blob Class – A class with too many instance variables that tries to do more than it should. Blob classes cannot usually be sniffed out from the beginning, as the sizes increase over time.
- Lazy Class or Freeloader – The opposite of a blob class. This class does too little.
- Middle Man – Middle man is a class with lots of methods delegated to other classes.
- Feature Envy – A class with a method that is more interested in a different class from the one it currently resides in.
- Data Clump – When large sizes of data clump together in different areas.
- Inappropriate Intimacy – This occurs when a class has dependencies on implementation details of a different class.
- Parallel Inheritance Hierarchy – Whenever a subclass is created for a single class, a subclass must be made for other classes.
- Downcasting – A typecast that changes the abstraction model.
- Refused Bequest – A subclass that does not use the methods or data of the super class.
- Cyclomatic Complexity – A class with excessive branches and loops.
- Loose Class Names – Loose class names occur when a class name is not specific enough. Loose classes do not define the purpose of the class clearly. Loose class names can also easily be redefined by mistake.
It has also been shown in work by Khomh et al classes affected by even one smell have a higher chance of change- and fault-proneness than non-smelly classes.
Method Level Smells
These smells take into account the following:
- Long Method – Overly long procedures that are extremely difficult to comprehend, often resulting in spaghetti code.
- Speculative Generality – Methods which only have test cases as users.
- Message Chains – A method that calls a method that calls a method that calls…
- God Line – Excessively long lines of code
How Do You Fix Code Smells?
Now that you are aware of the different types and levels of code smells, it is time to begin the activity of fixing them. You can begin with the implementation of the code review process. Create a code smell reference list to document all of the smells you find. Often, those with experience in software development may begin to attempt to identify bad smells manually, but many code smells cannot be found without automated code smell detection tools.
Once you have used the code smell detectors to find smelly code and created your code smell reference list, the next step in the process is to begin refactoring. Refactoring involves the process of altering the software in a way that does not change the program’s external behavior. It is not necessarily one of the bug-fixing activities, but it does help to make you aware of any bad code and poor implementation choices, as well as any effects of code smells. Overall, refactoring will greatly improve the internal structure of your code.
Refactoring involves dividing your lines of code into smaller sections, often according to the catalog of code smells that you have discovered. Upon the detection of code smells, you can then decide to remove them or replace them with non-smelly classes and better code in order to improve code quality and enhance the simplicity, flexibility, or performance of your program.
The objective of refactoring is to eliminate bad code and smelly classes, while also limiting continual damage and staying within operating limits. Once you have refactored, use code review tools and run tests to make sure that everything is still working properly. If smelly classes or other design issues still remain, refactor again. Sometimes some reverse engineering may need to be involved in order to solve the problem.
While you may not be able to remove every single smell, the presence of code smells in your code can be a big problem. It means that your code is not operating as efficiently as possible. By performing regular maintenance activities, such as creating a code smell reference list and refactoring, you’re more likely to reduce the impact of code smells. This will increase your software quality and save you money.
What are Some Popular Code Smell Detection Tools?
Removing some code smells can seem relatively straightforward. To solve middle man issues, simply delete the extra methods. With a blob class, you must be very deliberate about the responsibility of the class and always maintain a high level of cohesion. Loose class names may just need a stricter class name.
But the detection of code smells, crafting the code smell reference list, and removing every single code smell in all of your lines of code can be a laborious activity, especially as project sizes continue to increase. Trying to find all relevant code smells manually is nearly impossible. This is where automated code review tools can come into play. These code review tools and detection tools are so popular and important that many previous studies have been written by Figueiredo, Moha et al, and others.
Today, there are many popular tools for code smell detection. Some tools include inFusion, Jdeodorant, PMD, and JspIRIT. Many code review tools may only be dedicated to a certain programming language or not dedicated enough, so be sure to find the tool that works best for you, your team, and your repository. Today, many code smell detection tools can help you classify and resolve any relevant code smells quickly and easily. They can often scan any repository you may have and display code smells in that way.
Whether it’s a conference on software maintenance or a conference on software engineering, throughout the years, many reports have been created, studying code smells in subject systems, industrial systems, open-source systems and others. Systems of large sizes or small sizes all can suffer from code smells.
According to a study by Aiko Yamashita (Yamashita A, conference on software maintenance, 2013), the detection of code smells in software can help to improve design. In this way, the impact of code smells is not necessarily bad, as these code smell instances can actually help you to improve your code. Regardless of how you look at it, identifying the presence of code smells and removing them is important for the maintainability of software systems. The implementation of detection tools can save you time and money in the long run. And that’s something that everyone with experience in software development can be in agreement about.
Sider Scan Supports Code Smells Detection
Try Sider Scan, our original duplicate code detection tool, which can find duplicates and bugs based on duplicate code. It can scan your codebase and provide an assessment on application level smells and opportunities to refactor code.