Software Engineering Modern Approaches Eric Braude and Michael Bernstein 1 Chapter 24. Refactoring 2 © 2010 John Wiley & Sons Ltd. The Software Development Lifecycle Learning Goals for This Chapter Planning Maintenance Testing Implementation Requirements analysis Design Phase most relevant to this chapter is shown in bold © 2010 John Wiley & Sons Ltd. • What is refactoring? • How does refactorings work at large scales? • How do you refactor at the method level? • Can you reorganize classes using refactoring? Reorganize data? • Can you refactor at the module/package level? • In what way is refactoring essential for agile projects? • How is refactoring used in non-agile projects? • How does refactoring relate to design patterns? 3 Using a Refactoring Wizard Shift/Alt/R © 2010 John Wiley & Sons Ltd. 4 Fowler’s Refactoring Taxonomy 1. Big Refactorings 2. Composing Methods 3. Moving Features Between Objects 4. Organizing Data 5. Dealing With Generalization 6. Simplifying Conditional Expressions 7. Making Method Calls Simpler © 2010 John Wiley & Sons Ltd. 5 Big Refactorings 1: Tease Apart Inheritance * Employee SoftwareEmp MaintceEmp ClericalEmp FulltimeSoftwareEmp FulltimeMaintceEmp FulltimeClericalEmp ParttimeSoftwareEmp ParttimeMaintceEmp ParttimeClericalEmp RetiredSoftwareEmp RetiredMaintceEmp RetiredClericalEmp *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 6 Big Refactorings 1: Tease Apart Inheritance * Employee MaintceEmp SoftwareEmp ClericalEmp FulltimeSoftwareEmp FulltimeMaintceEmp FulltimeClericalEmp ParttimeSoftwareEmp ParttimeMaintceEmp ParttimeClericalEmp RetiredSoftwareEmp RetiredMaintceEmp RetiredClericalEmp SoftwareEmp Employee MaintceEmp © 2010 John Wiley & Sons Ltd. Status ClericalEmp Fulltime Parttime Retired *Fowlers’ taxonomy 7 Big Refactorings 2*: Convert Procedural Design to Objects Control startGame() displayCharacter() moveCharacter() VideoGame GameCharacter *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 8 Big Refactorings 2*: Convert Procedural Design to Objects Control startGame() displayCharacter() moveCharacter() © 2010 John Wiley & Sons Ltd. VideoGame GameCharacter VideoGame start() GameCharacter display() move() *Fowlers’ taxonomy 9 Big Refactorings 3*: Separate Domain from Presentation Account name balance … displayStandard() displayHTML() *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 10 Big Refactorings 3*: Separate Domain from Presentation Account name balance … displayStandard() displayHTML() StandardAccountGUI display () Account name balance … HTMLAccountGUI display () *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 11 Big Refactorings 4*: Extract Hierarchy Project *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 12 Big Refactorings 4*: Extract Hierarchy Project Project SoftwareEngineeringProject MobileApplication CustomerEntertainmentProject DesktopApplication *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 13 Composing Methods* • Extract method • Inline method • Inline temp (remove a temporary variable) • Replace temp with query (i.e., a function) • Introduce explaining variable (to replace complicated expression) • Split temporary variable (i.e., used more than once) • Remove assignment to parameters • Replace method with method object *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 14 Moving Features Between Objects 1* • Move Method – Trades off method holding vs. usage • Move Field – Trades off holding vs. usage • Extract Class – Encapsulate a set of attributes and methods of a class • Inline Class – Opposite of Extract Class *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 15 Moving Features Between Objects 2* • Hide Delegate – Hide class dependencies from client classes** • Remove Middle Man – Opposite of Hide Delegate *Fowlers’ taxonomy ** See below © 2010 John Wiley & Sons Ltd. 16 Hide Delegates Client © 2010 John Wiley & Sons Ltd. Class1 Class2 method2 () 17 Hide Delegates Class1 Client Class2 method2 () Class1 method1() Client Key: = changed © 2010 John Wiley & Sons Ltd. delegate Class2 method2() delegate.method2() 18 Organizing Data 1* • Self Encapsulate Field – Change direct access of an attribute to accessor use • Replace Data Value with Object • Change Value to Reference class Order { Customer customer;…. class Order { private Customer getCustomer( String ….) • Change Reference to Value • Replace Array with Object *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 19 Organizing Data 2* • Change Unidirectional Association to Bidirectional – (Only if necessary.) Install backpointer. • Change Bidirectional Association to Unidirectional – Find a way to drop; consider third party • Replace “Magic Number” with Constant • Encapsulate Field – public attribute to private/accessor *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 20 Organizing Data 3* • Replace Record with Data Class – Simplest object with private data field, accessor • Replace Type Code with Class Account … type *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 21 Organizing Data 3* • Replace Record with Data Class – Simplest object with private data field, accessor • Replace Type Code with Class Account … type Account … © 2010 John Wiley & Sons Ltd. AccountType REGULAR: AccountType BIG_DISCOUNT: AccountType SMALL_DISCOUNT: AccountType *Fowlers’ taxonomy 22 • Replace Type Code with Subclass Organizing Data 4* Account … type • Replace Type Code with State/Strategy Account … type *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 23 • Replace Type Code with Subclass Account … type Organizing Data 4* Account … RegularAccount WholesaleAccount • Replace Type Code with State/Strategy Account … type Account … RegularAccountType © 2010 John Wiley & Sons Ltd. AccountType … WholesaleAccountType *Fowlers’ taxonomy 24 Dealing with Generalization 1* *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 25 Dealing with Generalization 2* • Extract Subclass Order quantity discount minimum type • Extract Superclass Manager name salary numSupervisees © 2010 John Wiley & Sons Ltd. Engineer name salary skillSet *Fowlers’ taxonomy 26 Dealing with Generalization 2* • Extract Subclass Order quantity discount minimum type • Extract Superclass Manager name salary numSupervisees © 2010 John Wiley & Sons Ltd. Engineer name salary skillSet Order quantity WholesaleOrder discount minimum Employee name salary Manager numSupervisees Engineer skillSet *Fowlers’ taxonomy 27 Dealing with Generalization 3* • Extract Interface Manager name salary numSupervisees billRate Engineer name salary skillSet billRate • Collapse Hierarchy – Inherited class not special enough *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 28 Dealing with Generalization 3* • Extract Interface Manager name salary numSupervisees billRate Billable getRate() Engineer name salary skillSet billRate • Collapse Hierarchy Employee getName() getSalary() Manager numSupervisees Engineer skillSet – Inherited class not special enough *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 29 Dealing with Generalization 4*: Form Template Method BicycleAssemblyInstructions writeBikeInstructions() TricycleAssemblyInstructions writeTrikeInstructions() *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 30 Dealing with Generalization 4*: Form Template Method BicycleAssemblyInstructions writeBikeInstructions() TricycleAssemblyInstructions writeTrikeInstructions() © 2010 John Wiley & Sons Ltd. AssemblyInstructions writePrep() writeSafety() writeWrapUp() writeManual() BicycleAssemblyInstructions writePrep() writeSafety() writeWrapUp() TricycleAssemblyInstructions writePrep() writeSafety() writeWrapUp() *Fowlers’ taxonomy 31 Fowler: Dealing with Generalization* • Replace Inheritance with Delegation Record lastChanged() Account • Replace Delegation with Inheritance *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 32 Fowler: Dealing with Generalization* • Replace Inheritance with Delegation Record lastChanged() Account record.lastChanged() Account lastChanged() record Record lastChanged() • Replace Delegation with Inheritance *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 33 Introducing Façade V U W © 2010 John Wiley & Sons Ltd. 34 Introducing Façade V U W package V U F W © 2010 John Wiley & Sons Ltd. 35 U V © 2010 John Wiley & Sons Ltd. Introduce Module Refactoring 36 U V Introduce Module Refactoring 1 VI U V © 2010 John Wiley & Sons Ltd. 37 Trnsctn Cust Modularize Refactoring Applied 2: Transaction/Customer ICust ICust Trnsctn Cust Trnsctn © 2010 John Wiley & Sons Ltd. CustFaç Cust 38 Reference Types Trnsctn Cust • Trnsctn has attribute of type Cust – Replacing Cust cust; with ICust cust; OK if … • Cust has only private attributes (i.e., use via methods only) • Trnsctn does not instantiate Cust instances • Trnsctn has method with parameter of type Cust – Replacing myMethod(Cust ) with myMethod(ICust ) OK if … • Cust has only private attributes (i.e., use via methods only) • Trnsctn has method returning type Cust – Replacing Cust myMethod(); with ICust myMethod(); OK • Trnsctn has method with variable of type Cust – Replacing Cust cust; with ICust cust; matter © 2010 John Wiley & Sons Ltd. Unresolved as a general 39 Agile Methods Obtain high-level requirements Obtain requirements for next period’s* segment Refactor to clean up * Typically 1-6 weeks © 2010 John Wiley & Sons Ltd. Refactor to accommodate new requirements Modify code and test code base to handle additional requirements 40