code smells episode 1 - that shit is vile
| rubyMapping code smells and how to get rid of those dank odors.
| Smell | Conditions | Spells |
|---|---|---|
| Duplicated code | Same expression in two or more methods of the same class | Extract Method |
| Same expression in two sibling subclasses | Extract Method, Pull Up Method |
|
| Similar expressions but not the same | Extract Method, Form Template Method |
|
| Methods that do same thing with different approaches | Substitute Algorithm |
|
| Same expression in the middle of two or more methods | Extract Surrounding Method |
|
| Same expressions in two or more unrelated classes | Extract Class, Extract Module |
|
| Long method | Too many temporary variables | Replace Temp with Query, Replace Temp with Chain |
| Too many method parameters | Introduce Parameter Object, Preserve Whole Object |
|
| Still too many method parameters | Replace Method with Method Object |
|
| Conditional expressions | Decompose Conditional |
|
| Loops | Collection Closure Methods |
|
| Large class | Too many responsibilities | Extract Class, Extract Subclass, Extract Module |
| Long parameter list | Parameter data can be obtained by asking an object | Replace Parameter with Method |
| Multiple parameters are sourced from an object | Preserve Whole Object |
|
| Multiple parameters are sourced from no logical object | Introduce Parameter Object, Introduce Named Parameter |
|
| Divergent Change | Class is often changed in different ways for different reasons | Extract Class |
| Shotgun Surgery | One change requires a slew of changes in a lot of different areas | Move Method, Move Field, Inline Class |
| Feature Envy | A method that seems more interested in another class than its own | Move Method, Extract Method |
| Data Clumps | Multiple data items that appear as instance variables | Extract Class |
| Multiple data items that appear as method parameters | Introduce Parameter Object, Preserve Whole Object |
|
| Primitive Obsession | Multiple individual data values as primitives | Replace Data Value with Object |
| Have conditionals that depend on typing | Replace Type Code with Polymorphism, Replace Type Code with Module Extension, Replace Type Code with State/Strategy |
|
| Have group of instance variables that should go together | Extract Class |
|
| Excessive primitives in parameter list | Introduce Parameter Object |
|
| Dissecting array | Replace Array with Object |
|
| Case Statements | Multiple case statements in different places that all need to be updated when new requirements are introduced | Extract Method, Move Method, Replace Type Code with Polymorphism, Replace Type Code with Module Extension, Replace Type Code with State/Strategy |
| Limited number of case statements | Replace Parameter with Explicit Methods |
|
| Have a nil case conditional | Introduce Null Object |
|
| Parallel Inheritance Hierarchies | Special case of Shotgun Surgery where everytime a subclass is created from one class, another subclass must also be created | Move Method, Move Field |
| Lazy Class | Classes or modules that aren’t doing enough | Collapse Hierarchy |
| Classes or modules that are borderline useless | Inline Class, Inline Module |
|
| Speculative Generality | Classes or modules that aren’t doing enough | Collapse Hierarchy |
| Unnecessary delegation | Inline Class |
|
| Methods with unused parameters | Remove Parameter |
|
| Methods with odd names | Rename Method |
|
| Temporary Field | An object whose instance variables are set only in certain conditions | Extract Class, Introduce Null Object |
| Message Chains | Long method chains that enforce tightly coupled code | Hide Delegate, Extract Method, Move Method |
| Middle Man | Encapsulation gone too far, e.g., when a class’s interface has too many methods only delegating to other classes | Remove Middle Man, Inline Method, Replace Delgation with Hierarchy |
| Inapproppriate Intimacy | Classes that are too tightly coupled, often interacting with private parts | Move Method, Move Field, Change Bidirectional Association to Unidirectional, Extract Class, Hide Delegate, Replace Inheritance with Delegation |
| Alternative Classes with Different Interfaces | Methods with different interfaces that perform the same function | Rename Method, Move Method, Extract Module, Introduce Inheritance |
| Incomplete Library Class | Existing library class missing functionality | Move Method |
| Data Class | Classes that have attributes and no other behavior or responsibility | Remove Setting Method, Encapsulate Collection, Move Method, Extract Method, Hide Method |
| Refused Bequest | Light to moderate misuse of inheritance: subclasses that do not need parent class’s data and behavior | Push Down Method |
| Severe misuse of inheritance: subclasses that do not support parent class’s public methods | Replace Inheritance with Delegation |
|
| Comments | Comments explaining a method | Extract Method |
| Comments explaining a method that has already been extracted | Rename Method |
|
| Comments declaring rules about required system state | Introduce Aasserion |
|
| Metaprogramming Madness | Situations where method missing is not required |
Replace Dynamic Receptor with Dynamic Method Definition, Extract Method |
Situations where method missing is required |
Isolate Dynamic Receptor |
|
| Disjointed API | Utilizing a library where a limited subset of configuration options are repeatedly reused | Introduce Gateway, Introduce Expression Builder |
| Repetitive Boilerplate | Overwhelming instances of duplication | Extract Method, Introduce Class Annotation |