Code smells: Difference between revisions
Jump to navigation
Jump to search
imported>Unknown user No edit summary |
No edit summary |
||
| (2 intermediate revisions by one other user not shown) | |||
| Line 3: | Line 3: | ||
<span id="types-of-code-smells"></span> | <span id="types-of-code-smells"></span> | ||
= Types of code smells = | = Types of code smells = | ||
<span id="long-function"></span> | <span id="long-function"></span> | ||
== Long function == | == Long function == | ||
* problem: they are really difficult to understand and you need to set a proper name | * problem: they are really difficult to understand and you need to set a proper name | ||
* solution: Extract it to another function or class | * solution: Extract it to another function or class | ||
== Mysterious name == | == Mysterious name == | ||
| Line 16: | Line 13: | ||
* solution: * Rename them | * solution: * Rename them | ||
* If there is no good name, may be a sign of bad design | * If there is no good name, may be a sign of bad design | ||
== Duplicated code == | |||
= | |||
* problem: you have the same structure in different parts of the code | * problem: you have the same structure in different parts of the code | ||
* solution: extract to a function / class | * solution: extract to a function / class<span id="long-parameter-list"></span> | ||
<span id="long-parameter-list"></span> | |||
== long parameter list == | == long parameter list == | ||
| Line 32: | Line 25: | ||
* problem: they are needed when code is not self explanatory | * problem: they are needed when code is not self explanatory | ||
* solution: code needs to be refactored | * solution: code needs to be refactored<span id="refused-bequest"></span> | ||
<span id="refused-bequest"></span> | |||
== refused bequest == | == refused bequest == | ||
| Line 40: | Line 31: | ||
* solution: * Create sibling class to push down all the parent code | * solution: * Create sibling class to push down all the parent code | ||
* Maybe hierarchy is not right | * Maybe hierarchy is not right | ||
== Global data == | == Global data == | ||
* problem: it is difficult to identify where the error is having data defined in the global scope. | * problem: it is difficult to identify where the error is having data defined in the global scope. | ||
* solution: use encapsulation into functions / classes | * solution: use encapsulation into functions / classes | ||
== Divergent change == | == Divergent change == | ||
* problem: a change in a context imply different modules | * problem: a change in a context imply different modules | ||
* solution: extract to a function / class | * solution: extract to a function / class | ||
== feature envy == | == feature envy == | ||
* problem: one module communicates more with another than with himself | * problem: one module communicates more with another than with himself | ||
* solution: move it from context | * solution: move it from context<span id="lazy-element"></span> | ||
<span id="lazy-element"></span> | |||
== lazy element == | == lazy element == | ||
* problem: it was expected to do many things but finally it wasn't needed | * problem: it was expected to do many things but finally it wasn't needed | ||
* solution: move to another function / class | * solution: move to another function / class | ||
== speculative generality == | == speculative generality == | ||
* problem: code that was added for a possible future feature but was never used | * problem: code that was added for a possible future feature but was never used | ||
* solution: delete it | * solution: delete it<span id="temporary-fields"></span> | ||
<span id="temporary-fields"></span> | |||
== temporary fields == | == temporary fields == | ||
* problem: field used for certain cases | * problem: field used for certain cases | ||
* solution: extract to a function / class | * solution: extract to a function / class<span id="message-chain"></span> | ||
<span id="message-chain"></span> | |||
== message chain == | == message chain == | ||
* problem: consecutive objects requests in depth | * problem: consecutive objects requests in depth | ||
* solution: delegate, extract or move | * solution: delegate, extract or move<span id="middle-man"></span> | ||
<span id="middle-man"></span> | |||
== middle man == | == middle man == | ||
* problem: inverse of message chain | * problem: inverse of message chain | ||
* solution: do not encapsulate too much | * solution: do not encapsulate too much<span id="insider-trading"></span> | ||
<span id="insider-trading"></span> | |||
== insider trading == | == insider trading == | ||
* problem: some modules communicate a lot with each other | * problem: some modules communicate a lot with each other | ||
* solution: move or delegate | * solution: move or delegate<span id="large-class"></span> | ||
<span id="large-class"></span> | |||
== large class == | == large class == | ||
* problem: it has too many fields, may lead to duplicated code and chaos | * problem: it has too many fields, may lead to duplicated code and chaos | ||
* solution: extract to another class | * solution: extract to another class<span id="mutable-data"></span> | ||
<span id="mutable-data"></span> | |||
== Mutable data == | == Mutable data == | ||
| Line 108: | Line 77: | ||
Paracelsus: the difference between a poison and something benign is the dose | Paracelsus: the difference between a poison and something benign is the dose | ||
[[Category:code refactoring]] | |||
Latest revision as of 08:47, 20 October 2025
Code smells are surface‑level indications in the source code—such as overly long methods, duplicated logic, or large classes—that aren’t bugs per se but suggest deeper design or maintainability problems. They act like warning flags: when you spot a smell (e.g., “God Object,” “Feature Envy,” or “Shotgun Surgery”), it tells you that the code probably violates sound design principles (like SRP or DRY) and may become fragile, hard to understand, or difficult to extend. Refactoring away smells early keeps the codebase cleaner, more modular, and easier to evolve over time.
Types of code smells
Long function
- problem: they are really difficult to understand and you need to set a proper name
- solution: Extract it to another function or class
Mysterious name
- problem: any name of variables, functions or classes that don't communicate what it does or how to use it
- solution: * Rename them
- If there is no good name, may be a sign of bad design
Duplicated code
- problem: you have the same structure in different parts of the code
- solution: extract to a function / class
long parameter list
- problem: too complicated to handle
- solution: use semantic objects such DTOs
comments
- problem: they are needed when code is not self explanatory
- solution: code needs to be refactored
refused bequest
- problem: implementation of interfaces doesn't need a lot of stuff from parent
- solution: * Create sibling class to push down all the parent code
- Maybe hierarchy is not right
Global data
- problem: it is difficult to identify where the error is having data defined in the global scope.
- solution: use encapsulation into functions / classes
Divergent change
- problem: a change in a context imply different modules
- solution: extract to a function / class
feature envy
- problem: one module communicates more with another than with himself
- solution: move it from context
lazy element
- problem: it was expected to do many things but finally it wasn't needed
- solution: move to another function / class
speculative generality
- problem: code that was added for a possible future feature but was never used
- solution: delete it
temporary fields
- problem: field used for certain cases
- solution: extract to a function / class
message chain
- problem: consecutive objects requests in depth
- solution: delegate, extract or move
middle man
- problem: inverse of message chain
- solution: do not encapsulate too much
insider trading
- problem: some modules communicate a lot with each other
- solution: move or delegate
large class
- problem: it has too many fields, may lead to duplicated code and chaos
- solution: extract to another class
Mutable data
- problem: some data updates may break something in another part of the code
- solution: Places where data is updated need to be monitored and reduced
Paracelsus: the difference between a poison and something benign is the dose