Presentation is loading. Please wait.

Presentation is loading. Please wait.

Refactoring (1). Software Evolution Cope with change Feature bloat Design decay Code duplications “Pattern time is refactoring time” Make future changes.

Similar presentations


Presentation on theme: "Refactoring (1). Software Evolution Cope with change Feature bloat Design decay Code duplications “Pattern time is refactoring time” Make future changes."— Presentation transcript:

1 Refactoring (1)

2 Software Evolution Cope with change Feature bloat Design decay Code duplications “Pattern time is refactoring time” Make future changes easier Simpler, cleaner, and more performant code

3 Refactoring is Changing Working Code! Management resistance If time is spent “cleaning up” working code, less time is spent implementing useful features. Risky It is risky to change working code as it may introduce new bugs. One risks lose sight of the original goal while keep changing the code

4 What 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 it internal structure. Disciplined way to clean up code Minimizes the changes of introducing bugs.

5 Refactoring as Patterns Principled Systemmatic Incremental, simple steps Safe

6 First Example A program to calculate and print a statement of a customer's charges at a video rental store. Movies Type of movies: regular, children's, new releases Frequent renter points

7 Initial Class Diagram

8 What's your impression of the code?

9 User Needs Changed! Want the statement shown on the Web with nice HTML formatting Charging rule is changed Movie classification is changed, the changes affect the charging rule and the points calculation...

10 First Step in Refactoring Write solid tests! Tests must be self checking Either pass test Or print detailed list of failures

11 Decomposing and redistributing statement() Find logic chunk of code and extract them into its own method switch statement is a good candidate  Extract to amountFor private method Find local variables  Not modified: pass in as parameter in new method each  Modified: if only one, return it ThisAmount Compile and test

12 Renaming Variables in Extracted Methods Good names communicate intention A key to clear code Changed: each -> aRental thisAmount -> result

13 Moving Amount Calculation amountFor method doesn't use information from Customer, so it shouldn't be in Customer class It uses information from Rental Move the code over Rename it getCharge Change customer.amountFor to test it If test passes, replace amountFor with getCharge everywhere Since it is not public, otherwise, leave the delegation

14 Extract Frequent Renter Points Again look for local variables Find the appropriate place to put the method frequentRenterPoints += each.getFrequentRenterPoints();

15 Remove Temporary Variables Temps encourage complex and long methods Replace them with new method calls thisAmount totalAmount frequentRenterPoints Trade-off with performance

16 Reuse of New Methods public String htmlStatement() { Enumeration rentals = _rentals.elements(); String result = " Rentals for " + getName() + " </ H1> \n"; while (rentals.hasMoreElements()) { Rental each = (Rental) rentals.nextElement(); //show figures for each rental result += each.getMovie().getTitle()+ ": " + String.valueOf(each.getCharge()) + " \n"; } //add footer lines result += " You owe " + String.valueOf(getTotalCharge()) + " \n"; result += "On this rental you earned " + String.valueOf(getTotalFrequentRenterPoints()) + " frequent renter points "; return result; }

17 Replace Conditional with Polymorphism The big switch is bad What if the classification movie type changes? Not good to witch on other object's data Move getCharge to Movie instead Do the same for getFrequentRenderPonits Now things varies with the type are in the type Ready for Movie inheritance?

18 What about this? Doesn't work well, as a movie's classification may be changed (e.g. from new release to regular)

19 Use State Pattern Add abstraction of Price Enable runtime change

20 Step One Make sure all the use of type code goes through getter / setter Create the Price classes abstract class Price { abstract int getPriceCode();} class ChildrensPrice extends Price { int getPriceCode() { return Movie.CHILDRENS; } class NewReleasePrice extends Price { int getPriceCode() { return Movie.NEW_RELEASE; } class RegularPrice extends Price { int getPriceCode() { return Movie.REGULAR; }

21 Step Two Change movie's accessors for the price code to use the new Price class public void setPriceCode(int arg) { switch (arg) { case REGULAR: _price = new RegularPrice(); break; case CHILDRENS: _price = new ChildrensPrice(); break; case NEW_RELEASE: _price = new NewReleasePrice(); break; default: throw new IllegalArgumentException("Incorrect Price Code"); }

22 Step Three Move each case to its corresponding concrete classes class RegularPrice... double getCharge(int daysRented){ double result = 2; if (daysRented > 2) result += (daysRented - 2) * 1.5; return result; }...


Download ppt "Refactoring (1). Software Evolution Cope with change Feature bloat Design decay Code duplications “Pattern time is refactoring time” Make future changes."

Similar presentations


Ads by Google