Code Smells 1
What are Code Smells? “[…] certain structures in the code that suggest (sometimes they scream for) the possibility of refactoring.” Fowler They are clear signs that your design is starting to decay Long term decay leads to “software rot”
Code Smells Duplicated code Long method Large class Long parameter list Message chain Feature envy Data class Switch statements Speculative generality Temporary field Refused bequest
Duplicate code Duplicate methods in subclasses Move to a superclass (consider creating one if it does not exist) Duplicate expressions in the same class Extract as a new method Duplicate expression in different classes Extract method, move to a common component
Long method Symptoms Will not fit on one page Cannot think of the whole Comments that introduce sections of the method Extract parts of the method as a new method Candidates include Loop body Place(s) that include comments Branches of if statements
Large class Symptoms More than a couple dozen methods More than half a dozen fields Split into component classes Extract superclass If using switch statement, split into subclasses
Single Responsibility Principle A class should only have one responsibility In other words: it should have only one reason to change
Long parameter list Introduce parameter object Only worthwhile if there are several methods with the same parameter list, and they call each other
Message Chain Symptoms Anything that looks like this customer.Address.State window.BoundingBox.Origin.X When it could look like this customer.State window.LeftBoundary
Law of Demeter Only talk to your immediate friends It allows you to use objects that were obtained via Parameters of the method Fields of the class Objects created in the method Global variables
Feature envy Symptoms Code that wished it was in another class It uses data from another class From Teacher.Classes.Add(class); Teacher.ClassLoad += 1; To teacher.AddClass(class);
Data class Symptoms Class that has no methods except for Property getters and setters Look for missing methods (Feature envy?) and move them to the class Look for classes using the data and merge in with those
Switch statement Symptoms Sign of missing polymorphism Replace with A method call and make a subclass for each case
Speculative generality Symptoms Interfaces/abstract classes that are implemented by only one class Unnecessary delegation Unused parameters
Temporary field Symptoms Instance variable is only used during part of the lifetime of an object i.e. it is only used while the object is initialized Move variable into another object (perhaps a new class)
Refused bequest Symptoms A class refuses bequest if it inherits another class but only overrides or specializes a small number of methods Parent class is too large Break class into separate classes Push down or pull up some of the methods Child class is not using the methods Inheritance is no needed; convert inheritance into composition
Other smells Non-localized plans Too many bugs Too hard to understand Too hard to change
Non-localized plan Adding a feature requires a plan. If adding a feature requires changing many parts of a program, it is called a non-localized plan e.g., Parallel class hierarchies – adding a class in one class hierarchy requires adding a class in another Example A new item class requires a new ItemFactory class
How to refactor a Non-localized plan Make a new object that represents everything that changes Methods that change together should stay together Many patterns address this kind of problem
Too many bugs If one part of the system has more than its share of the bugs, there is probably a good reason A growing number of bugs is the sign of software rot Redesign, rewrite, refactor
Too hard to understand Hard to fix bugs because you don’t understand the code Hard to change the code because you don’t understand it
Too hard to change Because of a lack of tests Because of (undocumented) dependencies Global variables Very large modules Importing too many classes (high coupling) Because of duplication or non-localized plans
It’s a sense “You will have to develop your own sense of how many instance variables are too many instance variables and how many lines of code in a method are too many lines.” Fowler
?
References