Refactoring PHP


Published on

Talk on refactoring based on the book Refactoring by Martin Fowler.

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Refactoring PHP

  1. 1. Refactoring Presentation for: South Florida PHP Users Group By: Adam Culp Twitter: @adamculp
  2. 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. 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. 4. Refactoring Rental class  Next we look at the Rental class.
  5. 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. 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. 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. 8. Refactoring Rewrite vs Refactor  Budget constraint  Time constraint  Rewrite is an excuse to NOT dig in someones code  Refactor is the best teacher
  9. 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. 10. Refactoring Step 1  Extract Method to move switch statement to its own method.
  11. 11. Refactoring Step 2  Variable names should make sense. (each > rental, thisAmount > result)
  12. 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. 13. Refactoring Step 4  Call getCharge() directly from statement() instead of using amountFor() as a middle man method.
  14. 14. Refactoring Step 5  Replace Temp with Query - Cleanup of call to getCharge(). Eliminate temp variables by calling method direct. Less maintenance.
  15. 15. Refactoring Step 6  Extract Method and move frequentRenterPoints to its own method in Rental class where it logically belongs.
  16. 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. 17. Refactoring Step 8  Also do Replace Temp with Query on frequentRentalPoints to eliminate more temp variables.
  18. 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. 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. 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. 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. 22. Refactoring Two hats  Adding Function Hat  Refactoring HatFirst we add functionality, they we refactor it, thenadd more functionality, ...
  23. 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. 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. 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. 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 … Dont tell (controversial?)  Find a way to work it into scheduling.  Overall it saves time, but some will never “see” it
  27. 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. 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. 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. 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. 31. Refactoring Thank you Adam Culp Twitter @adamculp