1. Refactoring
Presentation for:
South Florida PHP Users Group
By:
Adam Culp
Twitter: @adamculp
http://www.geekyboy.com
2. Refactoring
 Based on popular “Refactoring” Improving The
Design of Existing Code book, by Martin
Fowler.
 We will start in the code with an example.
 Tips and descriptions will be handled during the
example.
 In the example we are tasked with creating an
HTML representation of the customer
statement for a movie rental.
3. Refactoring
 Movie class
 With a new project we take
a look at the current
application a customer has
requested to be changed.
 We start with the Movie
class.
4. Refactoring
 Rental class
 Next we look at the Rental
class.
5. Refactoring
 Customer class p1
 With a new project we take
a look at the current app
that is about to be
changed.
 Next we look at part 1 of
the Customer class.
6. Refactoring
 Customer class p2
 With a new project we take
a look at the current app
that is about to be
changed.
 Next we look at part 2 of
the Customer class.
7. Refactoring
 Not terrible for a small quick and dirty application, but
if part of a larger application we have problems.
 Customer class doing far too much, and statement
method is too long.
 Impossible to reuse the statement for an HTML
representation.
 The customer also wants to be able to change how
they classify movies.
 As experienced developers we know that customers
will always come back six months from now and want
it changed in some way.
8. Refactoring
 Rewrite vs Refactor
 Budget constraint
 Time constraint
 Rewrite is an excuse to NOT dig in someone's code
 Refactor is the best teacher
9. Refactoring
 First step
 Build tests based on current “working” application,
so we can verify if we break something.
 Pre-load database with data or create fixtures
needed for tests, to ensure we have a constant to
compare test results.
 If we are not starting with a working application you
must first get the application working prior to
refactoring. Do not try to refactor a broken
application or you risk breaking it further, and end
up with a total rewrite.
10. Refactoring
 Step 1
 Extract Method to move switch statement to its own method.
11. Refactoring
 Step 2
 Variable names should make sense. (each > rental, thisAmount > result)
12. Refactoring
 Step 3
 Extract Method amountFor() to Rental class. It uses information from
Rental, but no information from Customer. We rename it to more
meaningful getCharge().
13. Refactoring
 Step 4
 Call getCharge() directly from statement() instead of using amountFor() as
a middle man method.
14. Refactoring
 Step 5
 Replace Temp with Query - Cleanup of call to getCharge(). Eliminate
temp variables by calling method direct. Less maintenance.
15. Refactoring
 Step 6
 Extract Method and move frequentRenterPoints to its own method in
Rental class where it logically belongs.
16. Refactoring
 Step 7
 We do Replace Temp with Query for totalAmount. Temp variables can be
a problem and really only serve a purpose within their own routine and
encourage long, complex routines.
17. Refactoring
 Step 8
 Also do Replace Temp with Query on frequentRentalPoints to eliminate
more temp variables.
18. Refactoring
 Step 9
 We are now able to create the HTML version of the statement, and we
rename the original to represent a Text version.
19. Refactoring
 Recap
 Most refactoring reduces code, while we increased it for
this example.
 We also duplicated a loop to make it happen 4 times
instead of once. (getFrequentRenterPoints,
getTotalCharge, getTotalFrequentRenterPoints)
 Optimizing and refactoring are different actions.
Refactor first, then optimize later if needed.
 More refactoring could further clean up Text and HTML
statements to DRY it up. (split out header/footer, etc.)
 Still need more refactoring to allow classification
changes by the customer.
20. Refactoring
 Step 10
 Move Method on getCharge() because it uses data in Movie, so should be
in the same class as the data.
21. Refactoring
 Step 11
 Replace Conditional with Polymorphism on getCharge() because it uses
data in Movie, so should be in the same class as the data.
22. Refactoring
 Two hats
 Adding Function Hat
 Refactoring Hat
First we add functionality, they we refactor it, then
add more functionality, ...
23. Refactoring
 Why Refactor?
 Without refactoring code decays
 As code is changed it loses structure, making it
harder to see design
 Regular refactoring preserves design
 Poorly designed = more code due to duplication
 Reduced code = easier to maintain
 Reduced code = easier to understand
 Helps find bugs
 Helps us program faster
24. Refactoring
 When to Refactor?
 Should not set aside time to refactor, it is just
something we do in short bursts
 Refactor because you want to do something, and
refactoring helps you do it
 Often a quick refactor can help developing new
functionalities move faster
 Rule of Three → see next slide
25. Refactoring
 Rule of Three
 When you add function
 Helps to learn code you need to modify
 Changes code that prevents the addition
 When you need to fix a bug
 Make code more understandable
 Usually highlights the bug
 During code review
 Code looks good to developer, but maybe not to
the team.
 More concrete results
26. Refactoring
 What do I tell my manager?
 For a tech saavy manager it may not be hard to
explain the benefits
 Quality centric manager stress quality aspects
 Perhaps introduce it as a review process
 There are many resources on Google about
value of reviews, inspections, or software
development process
 Schedule driven … Don't tell (controversial?)
 Find a way to work it into scheduling.
 Overall it saves time, but some will never “see” it
27. Refactoring
 Code “smells” as indicators
 Bad code “smells” and is a great way of indicating it
is time for a refactor.
 Duplicate Code
 Long Method
 Large Class
 Long Parameter (argument) List
 Divergent Change - if change is needed in
multiple areas to accommodate a change
 Shotgun Surgery – change causes ripple of other
needed changes
 Feature Envy – a method seems to use another
class instead of the one it is in
28. Refactoring
 Code “smells” as indicators
 More “smells”
 Data Clumps – if data items tend to accompany
one another
 Primitive Obsession
 Switch statements
 Parallel Inheritance Hierarchies – caused when
you need to create a subclass of one object
because you created a subclass of another
 Lazy Class – classes that do not do much and do
not pay for their extra weight
 Speculative Generality – constructs built for the
sake of possibility later
29. Refactoring
 Code “smells” as indicators
 More “smells”
 Temporary Field
 Message Chains – object asking for object that
asks for another object...
 Middle Man – directors in place but serving no
real purpose
 Inappropriate Intimacy – classes should not deal
too much with each others private parts
 Data Class – getters and setters, but nothing else
 Comments – where comments are used as
deodorant to cover a bad smell
30. Refactoring
 Tests and Refactoring
 You cannot properly refactor without tests in place.
 Writing tests is the first step of refactoring, and
should happen as you write the code in the first
place. (or before, as with TDD)
31. Refactoring
 Thank you
Adam Culp
http://www.geekyboy.com
http://github.com/adamculp
Twitter @adamculp