1 / 33

Refactoring

Refactoring. What is Refactoring?. “ Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.

montana
Download Presentation

Refactoring

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Refactoring

  2. What is Refactoring? “Refactoring is a disciplined technique for restructuring an existing body of code,altering its internal structure without changing its external behavior. Its heart is a series of small behavior preserving trans-formations. Each transformation (called a 'refactoring') does little, but a sequence of transformations can produce a significant restructuring. Since each refactoring is small, it's less likely to go wrong. The system is also kept fully working after each small refactoring, reducing the chances that a system can get seriously broken during the restructuring.” http://refactoring.com

  3. What 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 [Kerievsky]

  4. What Alerts Us to Refactor? • Code Smells • Signs that there might be something ugly in the design waiting to be refactored away • Examples: • Long Method • Long Parameter List • Duplicate Code • Large Class • Comments • Feature Envy • Middle Man • Message Chains • Shotgun Surgery

  5. Something to think about • The longer you wait before paying your debt, the bigger the bill—common sense • The bigger the mess, the less you want to clean it up—Joshua Kerievsky • Perfection is reached not when there remains nothing to add, but when there remains nothing to remove—Antoine de Saint-Exupéry, 1900-1944

  6. Metaphor: Clean As You Go Mrs. Beeton The Book of Household Management CLEAN AS YOU GO Quoted by Kevlin Henney and James Newkirk at JAOO 2004,featured in Joshua Kerievsky’s Refactoring to Patterns

  7. What is “mercilessly”? “The bigger the mess, the less you want to clean it up” – Joshua Kerievsky • Continuously. • Refactor as often as you possibly can • If you decide to leave a particular refactoring for later, know the cost of doing so! • Before or after. Not during. • Keep focused. You’ll do less mistakes and it’s easier to keep your head around things that way.

  8. Design Debt • What happens if you don’t refactor? you incur Design Debt • Design Debt refers to the unwanted consequences of letting sloppy design and programming exist in the codebase – it’s the software design equivalent for Technical Debt Workarounds instead of “form fit” additions • Over-engineering is Design Debt as well! [Cunningham]

  9. Design Income? If there’s Design Debt, then is there equivalent “Design Income” in the other end of the scale? • Up-front design could be considered Design Income. However, there’s a big risk of the potential Design Income becoming Design Debt because of over-engineering and wrongful assumptions. Due to this risk, up-front design should only be done for “sure things”. Then again, “sure things” are rarely big winners, so…  Up-front design is often a bad investment

  10. Refactoring and Design Patterns • Design Patterns are closely related to Refactoring: • Refactorings are transformations from one state to another • These states are often Design Patterns! [Alexander], [GoF], [Hillside]

  11. Preventing Regression • Unit tests • A good enough coverage lets us refactor with confidence that nothing was broken. • Automated tests get run. Manual tests don’t. • Functional tests • For the random situations where unit tests aren’t sufficient for preventing regression • Automated tests get run. Manual tests don’t. • Side-track: Test-Driven Development

  12. Rewriting vs. Refactoring • Rewriting != Refactoring • The word “refactoring” is often used in the context of a plain rewrite of existing code, which is most often a blatant mistake …however… • Refactoring ~ Rewriting • Some refactorings can be thought of as controlled rewrites in well-defined, small steps …and sometimes… • Refactoring ~ Deleting • Deleting code can boost a team’s performance

  13. Metaphor: John Thompson(from Refactoring to Patterns) John Thompson, hatter, makes and sells hats for ready money.

  14. Metaphor: John Thompson (cont’d) John Thompson

  15. Next Up… … a bunch of sample refactorings in Java

  16. RefactoringsRename Method • Mechanics: • Check to see whether the method signature is implemented by a super class or a subclass. If it is, these steps must be performed for each implementation. • Declare a new method with the new name. Copy the old body of code over to the new name and make any alterations to fit. • Compile. • Change the body of the old method so that it calls the new one. • Compile and test. • Find all references to the old method and change them to call the new one instead. Compile and test after each change. • Remove the old method. • Compile and test.

  17. Exercise 1-4-1:Rename Method • Task: • Rename the setAmount(float) method in example.Money to setValue(float) without using Eclipse’s refactoring wizard, relying on the steps described in exercise-1.4-1.txt

  18. RefactoringsRename Method (cont’d) • Observations • Lot of work for a small refactoring, and • Very mechanical work, but also • Easy to automate …which leads to this particular refactoring (and many others, of course) being well-supported by modern IDE’s such as Eclipse.

  19. RefactoringsPull Up Method • A slightly more complex refactoring involving inheritance • Mechanics: • Inspect the methods to ensure they are identical (yes, identical – if they aren’t, use Substitute Algorithm to make them identical) • If the methods have different signatures, change the signatures to the one you want to use eventually in the super class • Create a new method in the super class, copy the body of one of the methods to it, adjust, and compile. (you might need to Pull Up Field, first) • Delete one subclass method. • Compile and test. • Keep deleting subclass methods one at a time, testing until only the super class method remains. • Check if you can change any callers to refer to the super type instead.

  20. Exercise 1-4-2:Pull Up Field & Pull Up Method • Task: • Pull Up Field ‘name’ without using Eclipse’s refactoring wizard, relying on the steps described in exercise-1.4-2.txt • Pull Up Method ‘getName()’ without using Eclipse’s refactoring wizard, relying on the steps described in exercise-1.4-2.txt

  21. RefactoringsPull Up Method (cont’d) • Observations • Uses other, lower-level refactorings to accomplish a slightly bigger refactoring • Clearly more complex, but still feasible to automate

  22. if (customer == null) { plan = BillingPlan.basic(); } else { plan = customer.getPlan(); } RefactoringsIntroduce Null Object • Again, a slightly more complex refactoring. • Mechanics: • Create a subclass of the source class to act as a NullObject. • Create an isNull() method on the source class and the null class – for the source class the method should return false, for the null class it should return true. • Compile. • Find all places that can return a null when asked for a source object. Replace them to give out an instance of the null class instead. Compile and test after each change. • Find all places that compare a variable of the source type with null and replace them with a call to isNull(). Compile and test after each change. • Look for cases in which client code invokes a method if not null and do some alternative behavior if null. For each of these cases override the method in question in the null class with the alternative behavior originally implemented in client code. Remove the condition check for those that use the overridden behavior. • Compile and test.

  23. Exercise 1-4-3:Introduce Null Object • Task: • Introduce a Null Object to replace the null-check in the PricingMachine class, relying on the steps described in exercise-1.4-3.txt

  24. RefactoringsIntroduce Null Object (cont’d) • Observations • Transformation towards a design pattern • Seems difficult to automate • Has the potential of cleaning up significant amounts of error-prone, distracting code

  25. RefactoringsReplace Inheritance with Delegation • This doesn’t look too difficult, does it? • Mechanics: • Create a field in the subclass that refers to an instance of the super class. Initialize the field to ‘this’. • Change each method defined in the subclass to use the delegate field. Compile and test after changing each method. • Remove the subclass declaration and replace the delegate assignment with an assignment to a new object of the ex-super class type. • For each super class method, add a simple delegating method to the ex-subclass. • Compile and test.

  26. Exercise 1-4-4:Replace Inheritance with Delegation • Task: • Replace Inheritance with Delegation in the CollectionOfItems class, relying on the steps described in exercise-1.4-4.txt

  27. RefactoringsReplace Inheritance with Delegation (cont’d) • Observations • A relatively simple refactoring, clearly less complex than Introduce Null Object……so what’s the big deal?

  28. RefactoringsReplace Delegation with Inheritance • This is exactly the reverse of “Replace Inheritance with Delegation!” • Mechanics: • Make the delegating object a subclass of the delegate. • Compile. Use Rename Method to fix any name clashes between the two classes’ methods. • Set the delegate field to be the object itself. • Remove the simple delegation methods. • Compile and test. • Replace all other delegations with calls to the object itself. • Remove the delegate field.

  29. Exercise 1-4-5:Replace Delegation with Inheritance • Task: • Replace Delegation with Inheritance in the CollectionOfItems class, relying on the steps described in exercise-1.4-5.txt

  30. RefactoringsReplace Delegation with Inheritance • Observations • Exact reverse of Replace Inheritance with Delegation • Refactorings are often like this – a nice side-effect of being well-defined…

  31. RefactoringsReplace Type Code … …with Subclasses …with Strategy There’s no one-to-one mapping between code smells and solutions. Sometimes multiple refactorings provide slightly varying ways to climb out of the same hole…

  32. My Favorite Refactorings • There are some refactorings that one uses more than others. For me, the following are probably the ones I use the most: • Rename Method • Extract Method • Move Method • Rename Class • Extract Class • Inline Temp • Extract Constant • Low-level refactorings; thus encountered more often than e.g. Introduce Null Object and thus better supported by IDE’s.

  33. Tool Support • JAVA • Eclipse • IntelliJ IDEA • Borland JBuilder • NetBeans • RefactorIT plug-in for Eclipse, Borland JBuilder, NetBeans, Oracle JDeveloper • .NET • IntelliJ Resharper for Visual Studio .NET • Visual Studio .NET Team Studio 2005 (Forthcoming)

More Related