Download presentation
Presentation is loading. Please wait.
Published byMarvin McDowell Modified over 9 years ago
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
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] Design Debt
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
Refactorings Rename Method Mechanics: 1.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. 2.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. 3.Compile. 4.Change the body of the old method so that it calls the new one. 5.Compile and test. 6.Find all references to the old method and change them to call the new one instead. Compile and test after each change. 7.Remove the old method. 8.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
Refactorings Rename 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
Refactorings Pull 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
Refactorings Pull 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
Refactorings Introduce 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. if (customer == null) { plan = BillingPlan.basic(); } else { plan = customer.getPlan(); }
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
Refactorings Introduce 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
Refactorings Replace 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
Refactorings Replace Inheritance with Delegation (cont’d) Observations –A relatively simple refactoring, clearly less complex than Introduce Null Object… …so what’s the big deal?
28
Refactorings Replace 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
Refactorings Replace 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
Refactorings Replace 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)
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.