Software Engineering Modern Approaches Eric Braude and Michael Bernstein 1
Chapter 24. Refactoring © 2010 John Wiley & Sons Ltd. 2
Learning Goals for This Chapter 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? Requirements analysis Design Implementation Testing Maintenance Planning The Software Development Lifecycle Phase most relevant to this chapter is shown in bold © 2010 John Wiley & Sons Ltd. 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 SoftwareEmpClericalEmp FulltimeSoftwareEmp RetiredSoftwareEmp *Fowlers’ taxonomy MaintceEmp ParttimeSoftwareEmp FulltimeMaintceEmp RetiredMaintceEmp ParttimeMaintceEmp FulltimeClericalEmp RetiredClericalEmp ParttimeClericalEmp before © 2010 John Wiley & Sons Ltd. 6
Big Refactorings 1: Tease Apart Inheritance * Employee SoftwareEmpClericalEmp FulltimeSoftwareEmp Employee SoftwareEmpClericalEmp Status Fulltime Retired RetiredSoftwareEmp *Fowlers’ taxonomy ParttimeMaintceEmp ParttimeSoftwareEmp FulltimeMaintceEmp RetiredMaintceEmp ParttimeMaintceEmp FulltimeClericalEmp RetiredClericalEmp ParttimeClericalEmp before after © 2010 John Wiley & Sons Ltd. 7
Big Refactorings 2*: Convert Procedural Design to Objects Control startGame() displayCharacter() moveCharacter() VideoGame GameCharacter *Fowlers’ taxonomy before © 2010 John Wiley & Sons Ltd. 8
Big Refactorings 2*: Convert Procedural Design to Objects Control startGame() displayCharacter() moveCharacter() VideoGame GameCharacter VideoGame start() GameCharacter display() move() *Fowlers’ taxonomy before after © 2010 John Wiley & Sons Ltd. 9
Big Refactorings 3*: Separate Domain from Presentation Account name balance … displayStandard() displayHTML() *Fowlers’ taxonomy before © 2010 John Wiley & Sons Ltd. 10
Big Refactorings 3*: Separate Domain from Presentation Account name balance … displayStandard() displayHTML() Account name balance … StandardAccountGUI display () HTMLAccountGUI display () *Fowlers’ taxonomy before after © 2010 John Wiley & Sons Ltd. 11
Big Refactorings 4*: Extract Hierarchy Project *Fowlers’ taxonomy before © 2010 John Wiley & Sons Ltd. 12
Big Refactorings 4*: Extract Hierarchy Project SoftwareEngineeringProject CustomerEntertainmentProject *Fowlers’ taxonomy MobileApplication DesktopApplication before after © 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 ** See below *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 16
Hide Delegates Client Class1 Class2 method2 () © 2010 John Wiley & Sons Ltd. 17
Hide Delegates Client Class1 Class2 method2 () Client Class1 method1() Class2 method2() delegate delegate.method2() Key: = changed © 2010 John Wiley & Sons Ltd. 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
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 Organizing Data 2* *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 before © 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 … AccountType REGULAR: AccountType BIG_DISCOUNT: AccountType SMALL_DISCOUNT: AccountType *Fowlers’ taxonomy before after © 2010 John Wiley & Sons Ltd. 22
Organizing Data 4* Replace Type Code with Subclass Replace Type Code with State/Strategy Account … type Account … type *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 23
Organizing Data 4* Replace Type Code with Subclass Replace Type Code with State/Strategy Account … type RegularAccount Account … WholesaleAccount RegularAccountType AccountType … WholesaleAccountType Account … type Account … *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 24
Dealing with Generalization 1* *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 25
Extract Subclass Extract Superclass Dealing with Generalization 2* Order quantity discount minimum type Manager name salary numSupervisees Engineer name salary skillSet *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 26
Extract Subclass Extract Superclass Dealing with Generalization 2* Order quantity WholesaleOrder discount minimum Order quantity discount minimum type Manager name salary numSupervisees Engineer name salary skillSet Manager numSupervisees Engineer skillSet Employee name salary *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 27
Extract Interface Collapse Hierarchy –Inherited class not special enough Dealing with Generalization 3* Manager name salary numSupervisees billRate Engineer name salary skillSet billRate *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 28
Extract Interface Collapse Hierarchy –Inherited class not special enough Dealing with Generalization 3* Manager name salary numSupervisees billRate Engineer name salary skillSet billRate Manager numSupervisees Engineer skillSet Employee getName() getSalary() Billable getRate() *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 29
Dealing with Generalization 4*: Form Template Method TricycleAssemblyInstructions writeTrikeInstructions() BicycleAssemblyInstructions writeBikeInstructions() *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 30
Dealing with Generalization 4*: Form Template Method AssemblyInstructions writePrep() writeSafety() writeWrapUp() writeManual() TricycleAssemblyInstructions writePrep() writeSafety() writeWrapUp() BicycleAssemblyInstructions writePrep() writeSafety() writeWrapUp() TricycleAssemblyInstructions writeTrikeInstructions() BicycleAssemblyInstructions writeBikeInstructions() *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 31
Replace Inheritance with Delegation Replace Delegation with Inheritance Fowler: Dealing with Generalization* Record lastChanged() Account *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 32
Replace Inheritance with Delegation Replace Delegation with Inheritance Fowler: Dealing with Generalization* Record lastChanged() Account lastChanged() Record lastChanged() record record.lastChanged() *Fowlers’ taxonomy © 2010 John Wiley & Sons Ltd. 33
Introducing Façade U V W © 2010 John Wiley & Sons Ltd. 34
Introducing Façade U V W V W package © 2010 John Wiley & Sons Ltd. 35 U F
Introduce Module Refactoring UV © 2010 John Wiley & Sons Ltd. 36
Introduce Module Refactoring UV UV VI 1 © 2010 John Wiley & Sons Ltd. 37
Modularize Refactoring Applied 2: Transaction/Customer TrnsctnCust Trnsctn CustFaç TrnsctnCust ICust Cust © 2010 John Wiley & Sons Ltd. 38
Reference Types 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; Unresolved as a general matter Trnsctn Cust © 2010 John Wiley & Sons Ltd. 39
Modify code and test code base to handle additional requirements Agile Methods Obtain requirements for next period’s* segment * Typically 1-6 weeks Refactor to accommodate new requirements Obtain high-level requirements Refactor to clean up © 2010 John Wiley & Sons Ltd. 40