You are on page 1of 29

Refactoring

Improving the Design of Existing Code

Matthias Ringwald
Software Engineering Workshop,
December 5-6, 2005
What is Refactoring?

“Refactoring(noun): A change made to the internal


structure of a software to make it easier to
understand and cheaper to modify without
changing its observable behavior”

Martin Fowler, "Refactoring - Improving the design of existing code",


Addison Wesley, 1999.

Disclaimer: Most slides are derived from this book

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 2
Talk Overview

ƒ What is refactoring?
ƒ Why and when should you refactor?
ƒ Java refactorings in Eclipse
ƒ Advanced refactorings
ƒ Other languages & tools
ƒ Hints/Own Opinion/Take Home Message

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 3
Why should you Refactor?

ƒ Because Refactoring...
ƒ Improves the design of software
- the design of a program will decay over time
as people change code to realize short-term goal
ƒ Makes software easier to understand
- by refactoring, software gets cleaned up
ƒ Helps you to find bugs
- clarifying the structure exposes bugs
ƒ Helps you to program faster
- as a result from the previous three points

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 4
When to Refactor?

ƒ “If you do something similar the third time...”


ƒ When you add a feature
ƒ to understand the code or improve design
ƒ When you need to fix a bug
ƒ clear code => no bugs :)
ƒ As you do a code review
ƒ When you encounter a “bad smell”…

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 5
Bad Smells!

“Bad Smells” in code give a hint to refactor

ƒ Duplicate Code
ƒ The #1 bad smell !
ƒ Long Method
ƒ Large Class
ƒ …
ƒ Switch Statements ( … breed duplication … )
ƒ Comments ( … not bad by itself …. )
ƒ ... many more ( 23 in total )
December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 6
Java refactoring in Eclipse

DEMO

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 7
Refactoring Example

ƒ All refactorings are described in a template.

Collapse Hierarchy
ƒ Situation
ƒ A superclass and subclass are not very different
ƒ Plan
ƒ Merge them together
ƒ Motivation
ƒ [some explanation]

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 8
Refactoring Example: Collapse Hierachy (2)

ƒ Mechanics:
ƒ Choose which class is going to be removed:
superclass or subclasses
ƒ Use Pull Up Field and Pull Up Method or Push Down
Field and Push Down Method
ƒ Compile and test with each move
ƒ Adjust references to the class that will be removed to
use the merged class. This will affect variable
declaration, parameter types, and constructors
ƒ Remove empty class
ƒ Compile and test

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 9
Refactoring and Design Patterns

ƒ “Refactoring to Patterns” by Joshua Kerievsky,


Addison Wesley, 2005
ƒ Provides insights into the combination of
refactoring and design patterns
ƒ Watch out for design-pattern smells!
ƒ e.g. Singletonitis: “addiction to the Singleton pattern”
ƒ Refactorings can be used towards or away from
certain design patterns.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 10
Move Embellishment to Decorator

ƒ Situation:
ƒ Code provides an embellishment to a class' core
responsibility.
ƒ Plan:
ƒ Move the embellishment code to a Decorator.
ƒ Motivation:
ƒ Adding features makes a class complicated over time.
ƒ Place each embellishment in its own class and let that
class wrap the type of the object it needs to embellish.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 11
Move Embellishment to Decorator (2)

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 12
Hints

ƒ Automated tests are required


ƒ Refactoring is best done continuously
Trial & Error => Code & Refactor & Test
ƒ CVS does not support renaming, use SVN to
keep file history
ƒ Checking the long list of refactorings might help
once in a while

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 13
Other Languages & Tools

ƒ SmallTalk: The “Refactoring Browser”


ƒ C#: There are tools, too.
ƒ C/C++: SlickEdit IDE/Plug-In (300 USD)
ƒ Refactoring in C: rename {variables, functions},
extract function, modify parameter list
ƒ Scripting Languages?

ƒ List: www.refactoring.com/tools.html

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 14
Own Opinion

ƒ Most important software engineering technique


since Design Patterns
ƒ One of several Extreme Programming practices
that can stand out alone (like e.g. automatic
testing)
ƒ Got popular because of its inclusion into Eclipse

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 15
Take Home Message

ƒ No reason for not using it with Java


ƒ … and Eclipse is the tool for this
ƒ Even non-automatic refactorings will reduce
errors
ƒ After getting used to refactoring, check out
Kerievsky's book “Refactoring to patterns

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 16
Literature

ƒ www.refactoring.com
Martin Fowler's Site dedicated to Refactoring, more books there

ƒ Martin Fowler, "Refactoring - Improving the design of existing code",


Addison Wesley, 1999.

Must-read introduction.

ƒ Joshua Kerievsky, "Refactoring to Patterns", Addison Wesley, 2005.


Combines refactoring with design patterns by showing how

refactoring is used to change existing designs to, towards or away

from pattern implementation.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 17
Why people hesitate

ƒ Conventional wisdom would discourage


modifying a design
ƒ You might break something in the code
ƒ You have to update the documentation
ƒ => Both expensive
ƒ But, there are longer term concerns:
ƒ sticking with an inappropriate design
- Makes the code harder to change
- Makes the code harder to understand and maintain
- Very expensive in the long run

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 18
Bad Smells in Code

ƒ Duplicated Code. ƒ Lazy Class.


ƒ Long Method. ƒ Speculative Generality.
ƒ Large Class. ƒ Temporary Field.
ƒ Long Parameter List. ƒ Message Chains.
ƒ Divergent Change. ƒ Middle Man.
ƒ Shotgun Surgery. ƒ Inappropriate Intimacy.
ƒ Feature Envy. ƒ Alternative Classes with Different
ƒ Data Clumps. Interfaces.
ƒ Primitive Obsession. ƒ Incomplete Library Class.
ƒ Switch Statements. ƒ Data Class.
ƒ Parallel Inheritance Hierarchies. ƒ Refused Bequest.
ƒ Comments.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 19
Advanced Refactorings

ƒ Composing Methods
ƒ Moving Features Between Objects
ƒ Organizing Data
ƒ Simplifying Conditional Expressions
ƒ Making Method Calls Simpler
ƒ Dealing with Generalization

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 20
Composing Methods

ƒ Extract Method.
Inline Method.
Inline Temp.
Replace Temp with Query.
Introduce Explaining Variable.
Split Temporary Variable.
Remove Assignments to Parameters.
Replace Method with Method Object.
Substitute Algorithm.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 21
Moving Features Between Objects

ƒ Move Method.
Move Field.
Extract Class.
Inline Class.
Hide Delegate.
Remove Middle Man.
Introduce Foreign Method.
Introduce Local Extension.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 22
Organizing Data

ƒ Self Encapsulate Field.


Replace Data Value with Object.
Change Value to Reference.
Change Reference to Value.
Replace Array with Object.
Duplicate Observed Data.
Change Unidirectional Association to Bidirectional.
Change Bidirectional Association to Unidirectional.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 23
Organizing Data (2)

ƒ Replace Magic Number with Symbolic Constant.


Encapsulate Field.
Encapsulate Collection.
Replace Record with Data Class.
Replace Type Code with Class.
Replace Type Code with Subclasses.
Replace Type Code with State/Strategy.
Replace Subclass with Fields.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 24
Simplifying Conditional Expressions

ƒ Decompose Conditional.
Consolidate Conditional Expression.
Consolidate Duplicate Conditional Fragments.
Remove Control Flag.
Replace Nested Conditional with Guard
Clauses.
Replace Conditional with Polymorphism.
Introduce Null Object.
Introduce Assertion.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 25
Making Method Calls Simpler

ƒ Rename Method.
Add Parameter.
Remove Parameter.
Separate Query from Modifier.
Parameterize Method.
Replace Parameter with Explicit Methods.
Preserve Whole Object.
Replace Parameter with Method.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 26
Making Method Calls Simpler (2)

ƒ Introduce Parameter Object.


Remove Setting Method.
Hide Method.
Replace Constructor with Factory Method.
Encapsulate Downcast.
Replace Error Code with Exception.
Replace Exception with Test.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 27
11. Dealing with Generalization

ƒ Pull Up Field.
Pull Up Method.
Pull Up Constructor Body.
Push Down Method.
Push Down Field.
Extract Subclass.
Extract Superclass.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 28
11. Deal with Generalization (2)

ƒ Extract Interface.
Collapse Hierarchy.
Form Template Method.
Replace Inheritance with Delegation.
Replace Delegation with Inheritance.

December 5, 2005 Matthias Ringwald, Institut for Pervasive Computing, ETH Zurich, mringwal@inf.ethz.ch 29

You might also like