340 likes | 570 Views
SWE 316: Software Design and Architecture. Handout. Lecture # 20 Improving the existing design: Refactoring. To be able to improve the existing design using refactoring. Most of the material and the slides of this presentation are adopted from:
E N D
SWE 316: Software Design and Architecture Handout Lecture # 20Improving the existing design: Refactoring • To be able to improve the existing design using refactoring • Most of the material and the slides of this presentation are adopted from: • “Refactoring, Improving the Design of Existing Code” by Martin Fowler, Addison Wesley, 1999. • presentation by Martin Fowler. • http://www.refactoring.com
2/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References What is refactoring? • “Refactoring is the art of improving the design of existing code. Refactoring provides us with ways to recognize problematic code and gives us recipes for improving it.” [William C. Wake] • “A change to the system that leaves its behavior unchanged, but enhances some non-functional quality - simplicity, flexibility, understandability, ...” [Kent Beck]
3/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References What is refactoring? (cont...) • “The process of changing a software system in such a way that it does not alter the external behavior of the code, yet improves its internal structure” [Fowler] • Verify no change in external behavior by • Testing: in practice good tests are essential • Formal code analysis by tool
4/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References The two hats Adding Function • Add new capabilities to the system • Adds new tests • Get the test working Refactoring • Does not add any new features • Does not add tests (but may change some) • Restructure the code to remove redundancy Swap frequently between the hats, but only wear one at a time
5/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Why refactoring? (1 of 2) • To improve the software design • Makes the program easier to change • To make the software easier to understand • Write for people, not the compiler • Understand unfamiliar code • To help find bugs • Refactor while debugging to clarify the code
6/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Why refactoring? (2 of 2) • Some argue that good design does not lead to code needing refactoring but: • It is extremely difficult to get the design right the first time • Original design is often inadequate • You may not understand user requirements, if he does! • Refactoring helps you to: • Manipulate code in a safe environment • Understand existing code
7/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References When should you refactor? • To add new functionality: • Refactor existing code until you understand it • Refactor the design to make it easy to add • To find bugs: • Refactor to understand the code • For code reviews: • Immediate effect of code review
8/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Team techniques • Encourage refactoring culture • Nobody gets things right first time • Nobody can write clear code without reviews • Provide sound testing base • Tests are essential for refactoring • Build system and run tests daily • Pair programming • Two programmers working together can be quicker than working separately
9/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Creating your own refactorings • Consider a change to a program • Should it change the external behavior of the system • Break down the change into small steps • Look for points where you can compile and test • Carry out the change, note what you do • If a problem occurs, consider how to eliminate it in the future • Carry it out again, follow and refine the notes • After two or three times you have a workable refactoring
List of refactorings: 10/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Typical Refactorings
11/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References A Longer List (martinfowler.com/refactoring/catalog) • Add Parameter • Change Bidirectional Association to Unidirectional • Change Reference to Value • Change Unidirectional Association to Bidirectional • Change Value to Reference • Collapse Hierarchy • Consolidate Conditional Expression • Consolidate Duplicate Conditional Fragments • Convert Dynamic to Static Construction by Gerard M. Davison • Convert Static to Dynamic Construction by Gerard M. Davison • Decompose Conditional • Duplicate Observed Data • Eliminate Inter-Entity Bean Communication (Link Only) • Encapsulate Collection • Encapsulate Downcast • Encapsulate Field • Extract Class • Extract Interface • Extract Method • Extract Package by Gerard M. Davison • Extract Subclass
12/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References A Longer List (martinfowler.com/refactoring/catalog) • Extract Superclass • Form Template Method • Hide Delegate • Hide Method • Hide presentation tier-specific details from the business tier (Link Only) • Inline Class • Inline Method • Inline Temp • Introduce A Controller (Link Only) • Introduce Assertion • Introduce Business Delegate (Link Only) • Introduce Explaining Variable • Introduce Foreign Method • Introduce Local Extension • Introduce Null Object • Introduce Parameter Object • Introduce Synchronizer Token (Link Only) • Localize Disparate Logic (Link Only) • Merge Session Beans (Link Only) • Move Business Logic to Session (Link Only) • Move Class by Gerard M. Davison • Move Field • Move Method
13/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References A Longer List (martinfowler.com/refactoring/catalog) • Parameterize Method • Preserve Whole Object • Pull Up Constructor Body • Pull Up Field • Pull Up Method • Push Down Field • Push Down Method • Reduce Scope of Variable by Mats Henricson • Refactor Architecture by Tiers (Link Only) • Remove Assignments to Parameters • Remove Control Flag • Remove Double Negative by Ashley Frieze and Martin Fowler • Remove Middle Man • Remove Parameter • Remove Setting Method • Rename Method • Replace Array with Object • Replace Assignment with Initialization by Mats Henricson • Replace Conditional with Polymorphism • Replace Conditional with Visitor by Ivan Mitrovic • Replace Constructor with Factory Method
14/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References A Longer List (martinfowler.com/refactoring/catalog) • Replace Data Value with Object • Replace Delegation with Inheritance • Replace Error Code with Exception • Replace Exception with Test • Replace Inheritance with Delegation • Replace Iteration with Recursion by Dave Whipp • Replace Magic Number with Symbolic Constant • Replace Method with Method Object • Replace Nested Conditional with Guard Clauses • Replace Parameter with Explicit Methods • Replace Parameter with Method • Replace Record with Data Class • Replace Recursion with Iteration by Ivan Mitrovic • Replace Static Variable with Parameter by Marian Vittek • Replace Subclass with Fields • Replace Temp with Query • Replace Type Code with Class
15/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References A Longer List (martinfowler.com/refactoring/catalog) • Replace Type Code with State/Strategy • Replace Type Code with Subclasses • Reverse Conditional by Bill Murphy and Martin Fowler • Self Encapsulate Field • Separate Data Access Code (Link Only) • Separate Query from Modifier • Split Loop by Martin Fowler • Split Temporary Variable • Substitute Algorithm • Use a Connection Pool (Link Only) • Wrap entities with session (Link Only)
16/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Extract Method VERY SIMPLE YET, VERY USEFUL • You have a code fragment that can be grouped together • Turn the fragment into a method whose name explains the purpose of the method. • void printOwing(double amount) { • printBanner(); • //print details • System.out.println ("name:" + _name); • System.out.println ("amount" + amount); • } • void printOwing(double amount) { • printBanner(); • printDetails(amount); • } • void printDetails (double amount) { • System.out.println ("name:" + _name); • System.out.println ("amount" + amount); • }
17/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Steps for Extract Method • Create method named after intention of code • Copy extracted code • Look for local variables and parameters • Turn into parameter • Turn into return value • Declare within method • Compile • Replace code fragment with call to new method • Compile and test
A method is, or will be, using or used by more features of another class than the class it is defined on. Create a new method with a similar body in the class it uses most. Either turn the old method into a simple delegation, or remove it altogether. 18/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Move Method
19/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Steps for Move method • Declare method in target class • Copy and fit code • Set up a reference from the source object to the target • Turn the original method into a delegating method • Compile and test • Find all users of the method • Adjust them to call method on target • Remove original method • Compile and test
20/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Replace Temp with Query • You are using a temporary variable to hold the result of an expression. • Extract the expression into a method. Replace all references to the temp with the expression. The new method can then be used in other methods. • double basePrice = _quantity * _itemPrice; • if (basePrice > 1000) • return basePrice * 0.95; • else • return basePrice * 0.98; • if (basePrice() > 1000) • return basePrice() * 0.95; • else • return basePrice() * 0.98; • double basePrice() { • return _quantity * _itemPrice; • }
21/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Steps for Replace temp with Query • Find temp with a single assignment • Extract Right Hand Side of assignment • Replace all references of temp with new method • Remove declaration and assignment of temp • Compile and test
1 Employee Employee Type Employee ENGINEER : int SALESMAN : int type : int Engineer Salesman 22/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Replace Type Code with State • You have a type code which affects the behavior of a class but you cannot use subclassing. • Replace the type code with a state object.
1 Employee Employee Type Employee ENGINEER : int SALESMAN : int type : int Engineer Salesman 23/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Replace Type Code with State • class Employee { • private int _type; • static final int ENGINEER = 0; • static final int SALESMAN = 1; • static final int MANAGER = 2; • Employee (int type) { • _type = type; • } • intpayAmount() { • switch (_type) { • case ENGINEER: • return _monthlySalary; • case SALESMAN: • return _monthlySalary + _commission; • case MANAGER: • return _monthlySalary + _bonus; • default: • throw new RuntimeException("Incorrect Employee"); • } • } • : • : • } • M s
24/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Steps for Replace Type Code with State • Create a new state class for the type code • Add subclasses of the state object, one for each type code. • Create an abstract query in the superclass to return the type code. Override in subclasses to return correct type code • Compile • Create field in old class for the state object. • Change the type code query to delegate to the state object. • Change the type code setting methods to assign an instance of the subclass. • Compile and test.
25/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Bad Smells • You are not limited to those refactoring techniques! • Always check for: • Bad smells within classes • Bad smells between classes
26/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Obstacles to refactoring (1 of 2) • Complexity • Changing design is hard • Understanding code is hard • Possibility to introduce errors • Run tests if possible • Build tests • Cultural Issues • “We pay you to add new features, not to improve the code!” What should I do in these cases?
27/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Obstacles to refactoring (2 of 2) • Performance issue • Refactoring may slow down the execution • Normally only 10% of your system consumes 90% of the resources so just focus on 10 %. • Refactorings help to localize the part that need change • Refactorings help to concentrate the optimizations • Development is always under time pressure • Refactoring takes time • Refactoring better after delivery
28/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Summary • “The process of changing a software system in such a way that it does not alter the external behavior of the code, yet improves its internal structure” [Fowler] • Refactor to: • Improve the software design • Make the software easier to understand • Help find bugs • A catalog of refactoring exists: Extract Method, Move Method, Replace Temp with Query, etc… • Refactoring has some obstacles
29/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Resources http://www.refactoring.com “Refactoring, Improving the Design of Existing Code” by Martin Fowler, Addison Wesley, 1999. “Refactoring to Patterns” by Joshua Kerievsky, Addison Wesley, 2004.
30/30 Introduction Why refactoring? Typical Refactorings Examples Obstacles Summary & References Resources (cont...) “Refactoring Workbook”, by William C. Wake, Addison Wesley, 2003.