1 / 26

Refactoring - An Example

Refactoring - An Example. CSSE 514 Programming Methods 5/3/01 Source: Martin Fowler, Refactoring - Improving the Design of Existing Code. Addison Wesley, 1999. Customer. Movie. Rental. priceCode: int. daysRented: int. statement(). Class Diagram. 1. *. *. 1. aCustomer. aRental.

sebastian
Télécharger la présentation

Refactoring - An Example

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 - An Example CSSE 514 Programming Methods 5/3/01 Source: Martin Fowler, Refactoring - Improving the Design of Existing Code. Addison Wesley, 1999.

  2. Customer Movie Rental priceCode: int daysRented: int statement() Class Diagram 1 * * 1

  3. aCustomer aRental aMovie Interaction Diagram statement * [for all rentals] getMovie getPriceCode getDaysRented

  4. Refactoring • Systematically alter the source code of a program in order to improve its design • Correctness preserving • Step at a time • Frequent testing

  5. Design Attributes • Abstraction (information hiding) • Flexibility • Clarity • Avoid redundancy

  6. Possible Changes • HTML version of statement • Altered charging rules • New classes of movies

  7. Prerequisite • Build a solid set of tests • Simple to run • Report results (“.” or “F” or “E”) • Associated with each class

  8. Refactoring 1Decompose and Redistribute Statement Method • Extract method: switch statement code • Handle local variables: • Unmodified (each) passed in as a parameter • Modified (thisAmount) returned as result

  9. Refactoring 2Rename Variables • Provide more descriptive names • Avoid name conflicts to assure correctness

  10. Guidelines • Refactor while reading to gain understanding • Try to eliminate the need for comments • Try to eliminate the need for local variables in methods

  11. Refactoring 3Move Method • amountFor is in Customer, but it doesn’t use any Customer data • So move it to Rental • Give it a new name • Remove references to aRental from message invocations • Change method invocations to use new name

  12. Refactoring 4Replace Temp with Query • Local variables that are only set once in a method act like constants • Replace them with calls to the defining method • Assumes no side effect • May reduce performance • Improves understandability • Makes other refactorings easier

  13. Refactoring 5Extract FrequentRenterPoints Computation • Further simplify statement computation • New method (getFrequentRenterPoints) in Renter

  14. Refactoring 6Prepare to add htmlStatement • htmlStatement is a new method for formatting output in HTML instead of text • It should not be concerned with the rules for computing charges, just with how to format • Consequently, statements for computing charges should be factored into methods, even if this means duplicating loop code • These methods will be callable from both statement and htmlStatement

  15. Refactoring 7Add htmlStatement processing • One way in which this program might be extended is to add a second output format • Whenever a variation is contemplated for an object-oriented program, subtyping (inheritance) should be considered • To prepare for this, the commonalities between statement and htmlStatement should be recognized and factored out

  16. Refactoring 7: Steps • Define a method object to encapsulate the statement method in the form of a new Statement class with TextStatement and HtmlStatement subclasses • Rename statement method to value within the Statement classes and pass a Customer as argument • Add getRentals method to return an Enumeration of current Rentals • Relax visibility of getTotalCharge and getTotalFrequentRenterPoints

  17. Refactoring 7: Steps - 2 • Prepare methods for all format-specific functionality and replace existing code with calls to the new methods • Remaining calling method can be pulled up into Statement class • Declare abstract classes for format-specific methods

  18. Customer statement() htmlStatement HtmlStatement TextStatement Statement value(Customer) headerString(Customer) eachRentalString(Customer) footerString(Customer) headerString(Customer) eachRentalString(Customer) footerString(Customer) headerString(Customer) eachRentalString(Customer) footerString(Customer) Class Diagram

  19. Refactoring 8:Replace Conditional Logic on priceCode with Polymorphism • switch statements (or else ifs) are strong indicators of poor object-oriented coding practices • They should be replaced by subclasses and polymorphic methods

  20. Refactoring 8: Steps • First, note that the switch statement is discriminating on the type of the movie, so it should really be in the Movie class • Do the same with the getFrequentRenterPoints method • Now the way is prepared for subclassing Movie objects into Regular, Childrens, and NewRelease movies

  21. Refactoring 8: Steps - 2 • Unfortunately, this doesn’t work. Can you see why? • Movies in video stores can change their categories dynamically as, for example, when a New Release moves into the Regular category • But an objects can’t change its class dynamically

  22. Refactoring 8: Steps - 3 • There is a trick for overcoming this problem. It involves introducing a class solely for holding the type information • We will use the Price class with subclasses for ChildrensPrice, NewReleasePrice, and RegularPrice • These classes provide methods for getCharge and getFrequentRenterPoints

  23. Price Movie getCharge(days:int) getFrequentRenterPoints(days:int) getCharge(days:int) getFrequentRenterPoints(days:int) ChildrensPrice RegularPrice NewReleasePrice getCharge(days:int) getFrequentRenterPoints(days:int) getCharge(days:int) getCharge(days:int) Class Diagram

  24. Move type code behavior into Price class Move switch statement into Price class Replace switch statement with polymorphism Update Movie class to reflect changes Refactoring 8: Steps - 4

  25. Class Diagram

  26. Class Diagram

More Related