Title: Refactoring and code smells
1Refactoring and code smells
- Source Refactoring to Patterns ,Addison Wesley,
August 2004 - Presented by Hung Hsiang Chen
2Outline
- Introduction
- Code smells list
- Example
- Duplicated Code
3Introduction
- What is refactoring?
- Refactoring is a "behavior-preserving
transformation" - Martin Fowler defines it, "a change made to the
internal structure of software to make it easier
to understand and cheaper to modify without
changing its observable behavior"
4What Motivates Us to Refactor?
- Make it easier to add new code.
- Improve the design of existing code.
- Gain a better understanding of code.
- Make coding less annoying.
5Refactoring other support method
- Many Eyes
- Human-Readable Code
- Keeping It Clean
- Small Steps
- Design Debt
- Evolving a New Architecture
6Composite and Test-Driven Refactorings
- Composite refactorings
- Composite refactorings are high-level
refactorings composed of low-level refactorings.
Much of the work performed by low-level
refactorings involves moving code around. - A test-driven refactoring
- applying test-driven development to produce
replacement code and then swap out old code for
new code.
7Composite Refactoring
- The Benefits of Composite Refactorings
- They describe an overall plan for a refactoring
sequence. - They suggest nonobvious design directions.
- They provide insights into implementing patterns.
8Code smell
- 12 smells and some refactorings to consider when
you want to remove the smells.
Alternative Classes with Different Interface
Lazy Class Large Class Switch Statements
Combinatorial Explosion Oddball Solution
Duplicated Code Long Method Conditional
Complexity Primitive Obsession Indecent
Exposure Solution Sprawl
9Example
- Replace Constructors with Creation Methods
- Chain Constructors
10Replace Constructors with Creation Methods
11Mechanics
- 1. Find a client that calls a class's constructor
in order to create a kind of instance. Apply
Extract Method on the constructor call to produce
a public, static method. This new method is a
creation method. Now apply Move Method to move
the creation method to the class containing the
chosen constructor.Compile and test. - 2. Find all callers of the chosen constructor
that instantiate the same kind of instance as the
creation method and update them to call the
creation method.Compile and test.
12- 3. If the chosen constructor is chained to
another constructor, make the creation method
call the chained constructor instead of the
chosen constructor. You can do this by inlining
the constructor, a refactoring that resembles
Inline Method.Compile and test. - 4. Repeat steps 13 for every constructor on the
class that you'd like to turn into a Creation
Method. - 5. If a constructor on the class has no callers
outside the class, make it non-public.Compile.
13- 1. first step is to find a client that calls one
of Loan's constructors.
14- apply Extract Method on that call to produce a
public, static method called createTermLoan
15- apply Move Method on the creation method,
createTermLoan, to move it to Loan.
16- 2. Next, I find all callers on the constructor
that createTermLoan calls, and I update them to
call createTermLoan.
17- 3. The createTermLoan method is now the only
caller on the constructor. Because this
constructor is chained to another constructor, I
can remove it by applying Inline Method
18- 4. Now I repeat steps 13 to produce additional
creation methods on Loan.
Passing in null values to a constructor is bad
practice. It reduces the code's readability. It
usually happens because programmers can't find
the exact constructor they need, so instead of
creating yet another constructor they call a more
general-purpose one.
19(No Transcript)
20(No Transcript)
21- 5. The last step is to change the visibility of
the only remaining public constructor, which
happens to be Loan's catch-all constructor. Since
it has no subclasses and it now has no external
callers, I make it private
22Chain Constructors
- You have multiple constructors that contain
duplicate code. - Chain the constructors together to obtain the
least amount of duplicate code.
23(No Transcript)
24Mechanics
- 1. Find two constructors that contain duplicate
code. Determine whether one can call the other
such that duplicate code can be safely (and,
hopefully, easily) deleted from one of these
constructors. Then make the one constructor call
the other constructor such that duplicate code is
reduced or eliminated.Compile and test. - 2. Repeat step 1 for all constructors in the
class, including ones you've already touched, in
order to obtain as little duplication across all
constructors as possible. - 3. Change the visibility of any constructors that
may not need to be public.Compile and test.
25(No Transcript)
26- 1. I study the first two constructors. They do
contain duplicate code, but so does that third
constructor. I consider which constructor it
would be easier for the first constructor to
call. I see that it could call the third
constructor with a minimum amount of work. So I
change the first constructor
27- 2. I repeat step 1 to remove as much duplication
as possible. This leads me to the second
constructor.