difficult to understand, maintain, or evolve. They are not specific errors, but rather characteristics that indicate possible underlying issues. When identified, code smells can be considered as an invitation to delve deeper into the code and make improvements.
a specific task and extract it into a new function with a descriptive name. This function encapsulates the logic contained in the original code snippet and can be called elsewhere, avoiding code duplication
in a piece of code that can be extracted into a variable with a descriptive name. This technique helps improve code readability, understandability, and maintainability.
private and providing access methods (getters and setters) to manipulate it. This technique helps improve the encapsulation, control, and consistency of data access.
directly from outside the class and make it private. You then create accessor methods (getters) and possibly modification methods (setters) to interact with that variable.
parameters is being repeatedly passed to a method or function. This technique involves creating a new object that encapsulates these related parameters, simplifying the method call and improving code readability.
two or more distinct phases or different types of tasks. This technique involves separating these phases into separate methods or functions to improve the readability, modularity, and maintainability of the code.
tasks being performed within a single method or function. You then extract each phase into a separate method or function, allowing each to be more focused and specific in its responsibility.
functionality that can be better organized in a separate new class. This technique involves creating a new class and transferring related attributes and methods to that new class.
within an existing class that are related to a specific responsibility or functionality. You then extract those attributes and methods into a new class, making them more cohesive and making the code easier to maintain.
an unnecessary intermediary between other classes. This technique involves eliminating the middleman, allowing method calls to be made directly between the relevant classes.
as a go-between, simply passing method calls to another class without adding any significant value or logic. You then direct the method calls directly to the class being brokered.
access to a delegate object and that direct access is being overused or violating the principle of encapsulation. This technique involves hiding the delegate object behind methods of the class that encapsulate it, limiting direct access to the delegate.
exposing the delegate object and providing direct access to it. You then hide the delegate behind methods of the class that act as intermediaries, allowing the class to control how the delegate is accessed and preventing uncontrolled direct access.
located in a class that is not the best fit to contain it. This technique involves moving the function to another class that has more suitable responsibility or where the function can be more easily reused.
a function or method that is in a class where it doesn't fit well in terms of responsibility or cohesiveness. Then you move that role to a more appropriate class, ensuring the functionality is placed in the right context.
snippets that are no longer used and have no impact on the program's operation. This technique involves removing these unnecessary code snippets, simplifying and making the code cleaner and more readable.
identify an object that must be treated as a single entity and not as a value. So you create a new class to represent that object, where equality is based on identity rather than object content. It then replaces occurrences of the value object with references to the new class.
with many branches and the logic becomes difficult to understand and maintain. This technique involves breaking down the condition into smaller, clearer parts, making the code easier to understand and maintain.
you need to guarantee a specific condition. You then add an assertion that checks for that condition, and if the condition isn't true, an error or exception is thrown.
is no longer necessary or relevant. You then remove the intermediate subclasses and move their attributes and behaviors directly into the parent class. This simplifies the hierarchy, reduces complexity, and improves code readability.