Code Smell – A General Introduction and it’s Type
The term code smell was first introduced by Kent Back, an American Software Engineer and the creator of extreme programming. When we work on an application and write codes for it, we see a few patterns that are needed to be refactored. Those patterns either duplicates, or complicates, or might make code dependent on other code. Such patterns are called Code Smells and detection of such code is called Code Smelling.
Code Smells are not the bugs of the program. With code smells too, your program might work just fine. They do not prevent the program from functioning or are incorrect. They just signify the weakness in design and might increase the risk of bugs and program failure in the future.
According to the author of the book, “Refactoring” quoted refactoring as: The process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure. Code Smells motivates for Code Refactoring.
Code refactoring has many advantages and disadvantages. For instance: The size of code decreases, confusing coding is properly restructured. Let’s discuss the types of code smell and some tips to remove it from your code much cleaner, clear, and simpler to understand.
Types of Code Smells
Although there are more than a hundred of code smells. The list of the most common and the most repeating code smells are given below. These are broadly divided into 2 main categories.
- Within Classes
- Between Classes
Code Smells Within Classes
- Comments: Yes, Comments are code smells too. It is like deodorant to the code. Comments are proof that the code is not self-documenting or intention-revealing. The best comment is the name of a class or method. If comments explain a few lines of complex code or a complex expression, it should be made as a complete another function/ sub-expression respectively.
- Long Method: A long method contains too many lines of code. Any code with more than 25 lines of code should make you question. It could be solved using refactoring techniques like changing expression into sub-expression, complex codes into a new function in order to make a function or method a small and easy to read without changing its functionality.
- Long Parameter List: Any function with more parameters is obviously more complex. One of the thumb rules is to use a maximum of 3 to 4 parameters in a function. To treat the code smell, check the values of the parameters, if it is the output of some other function, then instead of passing it as a parameter, pass it as a function. As a result, we’ll get a more readable, shorter code.
- Large Classes: A class contains many methods/lines of code/fields is considered a code smell. Classes usually start as a small one, but over time, they expand as the program grows.
To treat this code smell, further refactoring techniques could be done like, extract class, extract subclass, extract interface, duplicate observed data. As a result, we’ll not have to remember many attributes in the class.
- Duplicate Code: When a code is repeated for more than two times, merge it into a function or a method of the class. If the same code is found in two or more classes, using the extract method we can refactor the code smell. If the duplicate code is found inside a constructor of a class, we can use a pull-up constructor body.
Other refactoring methods to solve this are: Pull up field, Form Template method, Substitute Algorithm, etc.
- Dead Code: The code that is not being used. A function with no calls or the condition that never occurs. Delete unused code and unnecessary files. Remove the parameters that are not needed in the method or function. As a result, we’ll get simpler support and reduced code.
Code Smells Between Classes
- Data Classes: A class that just store data and no methods. These classes don’t contain any functionality. They can’t independently operate on the data that they own. A class should contain both data and methods. Use global or local variables to refactor this code smell. If the data class contains public data, we can use the Encapsulation Method to hide it.
Other refactoring techniques to solve this are: Move, Extract, and Remove Methods.
- Data Clumps: Data that looks similar maybe belongs to the same class. Consider using a superior class. For example, parameters for connecting to a database. These clumps should be merged into a new class. If data that is repeating data comprises the fields of a class, use extract class to move the fields to their own class or create their own class.
Other Refactoring Techniques to deal with this code smells are: Introducing parameter objects, Preserve the whole objects, etc.
- Alternative Classes with Different Interfaces: If two classes are similar on the inside, perhaps they can be modified to share a common interface. For example, The programmer who created one of the classes is might not aware that a similar class already existed or created by other programmers of the team.
Refactoring Techniques to deal with them are: Rename Method, Move, Add Parameter, Parameterize Method.
- Refused Bequest: A class inherits from other classes but not using the inheritance methods of its parent class. For example, Assume a class, body, human class, and animal class both are inherited from the class body. A car has a body too, it could inherit from the body class too, but that will not make any sense.
Refactoring Techniques to deal with this are: Replace inheritance with the delegation and Extract superclass.
- Lazy Class: A class doesn’t do enough to earn your attention, it should be deleted because it can cost your time and money both. For Example, a class that was designed to be fully functional but after some refactoring and change in code, it has become of no use or a little use maybe.
Inline Class and Collapsing Hierarchy can be used to make the code size smaller, easy to understand and maintain.
- Shotgun Surgery: A single fire causing multiple shots. A single change in classes may lead to cascading changes in several related classes. This can happen after the overzealous application of Divergent Change. Use of Move Method and Move Field could be done to make the code easier to maintain and less duplicated.