This document discusses bad smells in code that indicate refactoring may be needed. It defines refactoring as restructuring code without changing its external behavior to improve design, readability, and maintainability. Common bad smells include duplicated code, long or complex methods and classes, unused variables, primitive data types when objects could be used, and code that depends too much on other classes rather than being self-contained. The document provides examples of refactoring techniques to address each smell, such as extracting methods, replacing conditionals with polymorphism, and removing unnecessary dependencies between classes.
4. Defining Refactoring
Refactoring (noun)
• a change made to the internal structure of
software to make it easier to understand and
cheaper to modify without changing its
observable behavior.
Refactor (verb)
• to restructure software by applying a series of
refactorings without changing its observable
behavior
4
5. Why Should You Refactor?
To improve the design of software
To make software easier to understand
• Somebody else will eventually have to read your
code
To help you find bugs
To help you program faster
5
6. When to do Refactoring
1. Refactor when you add function
• Helps you to understand the code you are modifying
• Sometimes the existing design does not allow you to easily
add the feature
2. Refactor when you need to fix a bug
• the code was not clear enough for you to see the bug in
the first place
3. Refactor as you do a code review
• Code reviews help spread knowledge through the
development team
6
7. The Rule of three - Three strikes and you refactor
1. The first time you do something, you just do
it.
2. The second time you do something similar,
you wince at the duplication, but you do the
duplicate thing anyway.
3. The third time you do something similar, you
refactor.
7
9. Refactoring and Design
Refactoring changes the role of upfront
design
• Code the first approach you discover
get it working
refactor it into shape
A reasonable solution > looking for the
perfect solution
Refactoring can lead to simpler designs
without sacrificing flexibility
9
10. Refactoring and Unit Tests
Refactoring is strongly dependent on
having a good suite of unit tests
• To verify that the behavior is indeed preserved
Without unit tests the fear that
something may break.
10
13. Bad Smells in Code
Duplicated Code
Long Method
Large Class
Long Parameter List
Divergent Change
Shotgun Surgery
Feature Envy
Data Clumps
Primitive Obsession
Switch Statements
Parallel Inheritance
Hierarchies
Lazy Class
Speculative
Generality
Temporary Field
Message Chains
Middle Man
Inappropriate
Intimacy
Alternative Classes
with Different
Interfaces
Incomplete Library
Class
Data Class
13
14. Duplicated Code
Code that is the
same, or performs
the same function
are showing up in
multiple places
within a program
Having the same
expression in two
methods of the same
class Extract
Method
Having the same
expression in two
sibling subclasses
Extract Method + Pull
Up Field
Having duplicated
code in two unrelated
classes Extract
Class
14
15. Long Method
A lack of proper
encapsulation
It does too much
itself, and doesn't
delegate that work to
the proper
authorities
Prevent code reuse
To shorten a method
Extract Method
Passing a lot of
parameters
Replace Temp with
Query
Sliming down the
long list of
parameters
Introduce Parameter
Object, Preserve
Whole Object
15
16. Large Class
A class has taken on
too much
responsibilities.
• Complexity - hard to
understand.
• Bloat - take longer to
understand.
A class doing too
much too many
instance variables
duplicated code!
Extract Class +
Extract Subclass
16
17. Long Parameter List
The method is doing
too much - why does
it need all of that
information?
Understandability -
lots of parameters
will make code
harder to
understand.
difficult to use
changing them needs
more data
Replace Parameter
with Method when
you can get the data
in one parameter
making a request of
an object
17
18. Divergent Change
One class is commonly changed in different
ways for different reasons
To clean this up you identify everything that
changes for a particular cause and use Extract
Class to put them all together
18
19. Shotgun Surgery
Make a kind of
change have to
make a lot of little
changes to a lot of
different classes
Changes are hard to
find
Easy to miss an
important change.
Move Method and
Move Field to put all
the changes in a
single class
If no current class
looks like a good
candidate then create
one – Extract Class
Inline Class to bring
a whole bunch of
behavior together
19
20. Feature Envy
A method seems more interested in
another class
The method clearly wants to be
elsewhere Move Method
Only part of the method Extract
Method +Move Method
20
21. Data Clumps
See the same three or four data items together
in lots of places:
• Fields in a couple of classes
• Parameters in many method signatures
Use Extract Class to turn the clumps into an
object
For method parameters use Introduce
Parameter Object or Preserve Whole Object to
slim them down
21
22. Primitive Obsession
Using primitive data
types and method calls to
generate desired
outcomes, and could be
written in a more
descriptive and
sustainable way.
People new to objects are
sometimes reluctant to
use small objects for
small tasks
Replace Data Value with
Object on individual data
values
Replace Type Code with
Class if the value does not
effect the behavior
Have conditional that
depend on the type code
Replace Type Code with
Subclass or Replace Type
Code with State/Strategy
22
23. Switch Statements
See a switch statement polymorphism
Extract Method + Move Method
Only have a few case that effect a single
method then polymorphism is overkill
Replace Parameter with Explicit Methods
One of the conditional cases is null
Introduce Null Object
23
24. Parallel Inheritance Hierarchies
Make a subclass of one class you have to
make a subclass of another (this is a special
case of shotgun surgery)
To make sure that instances of one hierarchy
refer to instance of another
Move Method + Move Field the hierarchy on
the referring class disappears
24
25. Lazy Class
A class that is not
carrying its weight
should be eliminated
• Each class you create
costs money and time to
maintain and understand
Subclasses that are
not doing enough
Collapse Hierarchy
Nearly useless
components Inline
Class
25
26. Speculative Generality
Creating today what we
speculate will be needed
in the future
• the only users of a class or
method are test cases
Abstract classes that are
not doing enough
Collapse Hierarchy
Unnecessary delegation
Inline Class
Methods with unused
parameters should
Remove Parameter
Methods named with odd
abstract names
Rename Method
26
27. Temporary Field
See an object in
which an instance
variable is set only in
certain
circumstances
difficult to
understand because
we usually expect an
object to use all of its
variables
Use Extract Class to
create a home for
orphan variables
Eliminate conditional
code by using
Introduce Null Object
to create an
alternative
component for when
the variables are not
valid
27
29. Middle Man
Encapsulation often comes with delegation
sometimes delegation can go to far
Half the methods are delegated to another class
Remove Middle Man and talk to the object that really
knows what is going on
A few methods are not doing much Inline Method
If there is additional behavior Replace Delegation
with Inheritance to turn the middle man into a subclass
of the real object
29
30. Inappropriate Intimacy
Sometimes classes
become far too
intimate and spend
too much time in
each other's private
parts
Use Move Method and
Move Field to separate
the pieces to reduce the
intimacy
If the classes do have
common interests
• Extract Class to put the
commonality in a safe place
• Hide Delegate to let another
class act as a go-between
Change Bidirectional
Association to
Unidirectional
30
31. Alternative Classes with Different Interfaces
use Rename Method on any methods that do
the same thing but have different signatures
for what they do
Keep using Move Method to move behavior to
other classes until the protocols are the same
If you have to redundantly move code to
accomplish this, you may be able to use
Extract Superclass
31
32. Incomplete Library Class
The library is
insufficient for
your needs
If there are just a
couple of methods
that you wish the
library class had
Introduce Foreign
Method
If there is more extra
behavior you need
Introduce Local
Extension
32
33. Data Class
Classes that have fields,
getting and setting
methods, and nothing
else
Dumb data holders
Manipulated in far too
much detail by other
classes
public fields
Encapsulate Field
A collection of fields
Encapsulate Collection
Remove Setting Method
on any field that should
not be changed
Move Method to move
behavior into the data
class
If you can't move a whole
method, use Extract
Method to create a
method that can be
moved
33