Refactoring: Bad Smells

From Notes
Jump to navigation Jump to search

« previous | Chapter 3: Bad Smells | next »


Duplicated Code

Same code structure exists in more than one place or two sections of code perform same task.


Long Method

Function goes on for lines and lines; generally more than one screen of code


Large Class

Class is trying to do too much: too many instance variables

Long Parameter List

Function needs too many input parameters in order to function


Divergent Change

Making a change to the code is difficult: instead of jumping to place where change should be made, one small change results in the modification of several methods

  • Identify what changes each time, then use Extract Class to tie them together


Shotgun Surgery

Adding a feature or change results in modification of several classes or methods all over the place.


Feature Envy

A function uses so many getter functions of a different class to calculate a value (it wishes it were in that class)


Data Clumps

Similar data structures/items found in many places (i.e. instance variables, parameters)


Primitive Obsession

Code has heavy use of primitive data types rather than use of objects


Case Statements

Use of cases or conditionals in several areas


Parallel Inheritance Hierarchies

Similar to shotgun surgery: making subclass of one class requires you to make a subclass of another class. Classes usually have same prefixes in each class derivative/inheritance hierarchy.


Lazy Class

Class doesn't do enough to be "worth it's cost of upkeep" (Think: Class = $$$). Usually result of refactoring


Speculative Generality

Result of future features that never took shape: "Oh, I think we need the ability to this kind of thing someday. And this, and this, and this..." Machinery just gets in the way!


Temporary Field

Instance variable used only under certain conditions. Objects should need/use all of their variables


Message Chains

Client asks an object for another object, which then asks for another object, etc. to get to a function. Shows up as a long line of get_this methods or a lot of temps


Middle Man

Encapsulation of private variables (hiding them from rest of world) gone too far: one class's methods delegate to another class


Inappropriate Intimacy

"Sometimes classes become far too intimate and spend too much time delving into each other's private parts." — enough said.


Alternative Classes with Different Interfaces

Two classes do the same thing, but have different calls


Incomplete Library Class

Certain algorithms/behaviors of one class need to be available to other classes


Data Class

Classes that have attributes, but nothing else; manipulated too much by other classes


Refused Bequest

Subclasses don't use/need inherited data and function members or doesn't want to support public methods


Comments

Comments that are used to explain confusing code. By all means, write comments, but only when necessary (questions or concerns)


Metaprogramming Madness

Ruby's dynamic nature is misused: classes aren't defined in their own files, but scattered across many files. Key sign: method_missing


Disjointed API

Many configuration options for given Library API methods


Repetetive Boilerplate

Example: attr_reader (read-only), attr_accessor (read/write), and attr_writer (write-only) — getters and setters are so common in object-oriented languages that Yukihiro Matsumoto, creator of Ruby, decided to use shorthand to creating them.