Title: Refactoring
1Refactoring
- Joshua Knack
- CS 564
- Fall 2004
2Refactoring
- A brief history
- What is refactoring
- Benefits of refactoring
- Concerns of refactoring Smells
- Examples
- When should/shouldnt I refactor
3A brief history
- When did refactoring start? Really its always
been around. For as long as people have had to
deal with bad code, people have been refactoring.
- Refactoring officially came to the forefront
when Ward Cunningham and Kent Beck started to lay
the ground work for XP back in the 1980s
4A brief history, continued
- The next, and probably biggest hit came in 1992
when William Opdyke wrote his doctoral thesis
solely based around refactoring in regards to a
C framework - This work is the most substantial work on
refactoring to date
5What is refactoring?
- The process of changing a software system in such
a way that it does not alter the external
behavior of the code yet improves its internal
structure.
6Benefits of refactoring
- Improves the design of software
- Readability
- Ability to locate bugs
- Coding faster
7Improves the design of software
- The design of legacy programs will decay
- Changes to realize short term goals can cause a
design to lose its structure - Eliminating duplicate code
- does not fix something that was truly broken ...
but - Does make the system easier to modify
- Less code less to understand
8Readability
- The other user
- Changing the code to actually represent exactly
what you are trying to accomplish.
9Ability to locate bugs
- Through refactoring, you will get a much better
understanding of what the code is doing more than
just a quick glance over it. - This new understanding leads to
- ability to determine code that could cause
exceptions.
10Coding faster
- A good design is essential for RAD
- A more structured application inhibits RAD
- A poor design leads to problems down the road
with RAD that causes it to fail - Time spent locating and fixing bugs rather than
adding new functionality
11Concerns of refactoring
- Databases
- Changing interfaces
- Design changes that are difficult to refactor
- Smells
12Databases
- Most business applications are tightly coupled
with a database schema - Solution Data-Layer interface
- Data migration is also a major consideration when
choosing whether or not to refactor - Solution most object databases have support for
data migration. If not, BE CAREFULL!
13Changing interfaces
- Changing the code behind is much different than
changing the interface (think about the other
users) - Solution version control
14Design changes that are too difficult to refactor
- Not a very common, but a problem none the less
- Example
- refactoring a security system into an existing
application that currently has none. - Solution
- Putting more effort into the design rather than
spending time refactoring. - This is a judgment call made by the developer
15Smells
- Smells in your program are pieces of code that
need refactoring, or pieces of code that
refactoring could help clear up or make better.
16Examples of Smells
- Duplicate code
- Shotgun surgery
- Middle man
- Comments
- Temporary fields
17Refactoring Examples
- In Fowlers book, there are over 250 pages of
methods used to refactor code. I will cover some
of them in the format that he has presented them - Motivation
- Mechanics
- example
18Extract Method - Motivation
- Removing a piece of a long function or a piece of
a function that would be better suited on its own - Naming is also important for this method.
- If your method is doing more than the name
implies, you should move some of it to another
function.
19Extract Method - Mechanics
- Create a new function(named according to what it
does) - Copy extracted code from the source function to
the new function - Scan the code for any local variable references
that are in the source function - If any of them are specific to this new function,
add them as local variables
20Extract Method Mechanics, continued
- Are there any local variables being changed by
this function? - If yes, should they be moved out to a function of
their own? - Pass the local variables from the source function
to this function as necessary - Compile
- Remove functionality from source function and
replace with the new function call - Compile and test
21Extract Method Example - Before
- void printOwing()
- Enumeration e _orders.elements()
- double outstanding 0.0
-
- //print banner
- System.out.println()
- System.out.println( Customer Owes )
- System.out.println()
- //calculate outstanding
- while (e.hasMoreElements ())
- Order each (Order) e.nextElement()
- outstanding each.getAmount()
-
- //print details
- System.out.println(name _name)
- System.out.println(amount outsanding)
22Extract Method Example After 1
- void printOwing()
- Enumeration e _orders.elements()
- double outstanding 0.0
-
- printBanner()
- //calculate outstanding
- while (e.hasMoreElements ())
- Order each (Order) e.nextElement()
- outstanding each.getAmount()
-
- //print details
- System.out.println(name _name)
- System.out.println(amount outsanding)
-
- Void printBanner()
- //print banner
23Extract Method Example After 2
- void printOwing()
- Enumeration e _orders.elements()
- double outstanding 0.0
-
- printBanner()
- //calculate outstanding
- while (e.hasMoreElements ())
- Order each (Order) e.nextElement()
- outstanding each.getAmount()
-
- printDetails(outstanding)
-
- Void printDetails(double outstanding)
- //print details
- System.out.println(name _name)
- System.out.println(amount outsanding)
24Extract Method Example After 3
- void printOwing()
- double outstanding getOutstanding()
-
- printBanner()
- printDetails(outstanding)
-
- Void getOutstading()
- Enumeration e _orders.elements()
- //calculate outstanding
- while (e.hasMoreElements ())
- Order each (Order) e.nextElement()
- outstanding each.getAmount()
-
25Inline Temp - Motivation
- This is used when you are declaring a variable
that is only holding the value of a function call
so that it can be re-used only once.
26Inline Temp - Mechanics
- Declare the temp variable as final (const)
- This will help you ensure it is only used once
- Find a reference to this temp variable and
replace it with its associated function call - Compile and test after each change
- Remove the variable
- Compile and test
27Inline Temp - Example
- Before
- double basePrice anOrder.basePrice()
- return (basePrice gt 1000)
- After
- return (anOrder.basePrice() gt 1000)
28Parameterize Method - Motivation
- We sometimes see two functions that are very
similar in functionality, differing only by a
value being used within those functions
29Parameterize Method - Mechanics
- Create a parameterized function that can be
substituted for each repetitive function - Compile
- Replace old function calls with a call to the new
function - Compile and test
- Repeat for all similar functions
30Parameterize Method Example
- Before
- class Employee
- void tenPercentRaise()
- salary 1.1
-
- void fivePercentRaise()
- salary 1.05
-
-
- After
- class Employee
- void raise(double factor)
- salary (1 factor)
-
-
31Replace Parameter with Explicit Method -
Motivation
- This method is the opposite of the previous
method - We sometime come a cross a function that takes in
one or more parameters and then decides what type
of output to return based on those parameters.
That is not always intuitive to others viewing
your code
32Replace Parameter with Explicit Method - Mechanics
- Create an explicit function for each value of the
parameter - For each leg of the conditional, call the
appropriate new function - Compile and test after each change
- Replace each caller of the conditional function
with a call to the new function - Compile and test
- Remove the old conditional function
33Replace Parameter with Explicit Method Example
- Before
- static Employee create(int type)
- switch (type)
- case ENGINEER
- return new Engineer()
- break
- case SALESMAN
- return new Salesman()
- break
- case MANAGER
- return new Manager()
- break
-
-
34Replace Parameter with Explicit Method Example
After 1
- First Step Create appropriate functions to
replace the create() function - static Employee createEngineer()
- return new Engineer()
-
- static Employee createSalesman()
- return new Salesman ()
-
- static Employee createManager()
- return new Manager ()
35Replace Parameter with Explicit Method Example
After 2
- Second Step Replace all calls in the switch
statement for testing - static Employee create(int type)
- switch (type)
- case ENGINEER
- return Employee.createEngineer()
- break
- case SALESMAN
- return Employee.createSalesman()
- break
- case MANAGER
- return Employee.createManager()
- break
-
-
36Replace Parameter with Explicit Method Example
After 3
- After testing, you can change your code from
- Employee kent Employee.create(ENGINEER)
- to
- Employee kent Employee.createEngineer()
37When should I refactor
- The refactoring rule of 3
- When you add functionality
- When you need to fix a bug
- As you do a code review
38When shouldnt I refactor
- When existing code is bad enough that it should
just be re-written from scratch - When you are close to a deadline
39References
- http//www-106.ibm.com/developerworks/opensource/l
ibrary/os-ecref/ - http//users.cyberelectric.net.au/collins/Books/R
efactoring.htm - http//www.pbs.org/cringely/pulpit/pulpit20030508.
html - http//emw.inf.tu-dresden.de/de/pdai/Forschung/ref
actoring/refactoring_html/node34.htmlSECTION00410
000000000000000 - Fowler, Martin Refactoring Improving the Design
of Existing Code, 1999, Addison Wesley Longman,
Inc.