1 XP Extreme Programming Introduction into Refactoring Refactoring
- Slides: 53
1 XP: Extreme Programming Introduction into Refactoring, Refactoring to Patterns and Code Quality Refactoring Sina Golesorkhi(golesork@cs. uni-bonn. de) Thomas Schmickler(schmickl@cs. uni-bonn. de) Agile Software Development Lab Spring 2008 ROOTS
2 Overview Definition An Example in Eclipse Short Description Precondition of Refactoring Checklist Advantages of Refactoring Indicators for Refactoring are called „Bad Smells“ Agile Software Development Lab Spring 2008 ROOTS
3 Defintion What is Refactoring ? Refactoring (noun): a change made to the internal structure of software to make it easier to understand cheaper to modify without changing ist observable behavior. Refactor (verb): to restructure software by applying a series of refactorings. Goals: Better readability, comprehensibility • Better design • Better maintainability and reusability • Agile Software Development Lab Spring 2008 ROOTS
4 Example in Eclipse You can download the code from http: //www. schmickler. de/code. zip Agile Software Development Lab Spring 2008 ROOTS
5 Short Description Better readability, comprehensibility Sourcecode is for humans ! Bytecode for the machines. Agile Software Development Lab Spring 2008 ROOTS
6 Short Description Better readability, comprehensibility Sourcecode is for humans ! Bytecode for the machines. Some developers are proud of their cryptic code. Agile Software Development Lab Spring 2008 ROOTS
7 Short Description Better readability, comprehensibility Sourcecode is for humans ! Bytecode for the machines. Some developers are proud of their cryptic code. Some developers think they write the code only for themself. Agile Software Development Lab Spring 2008 ROOTS
8 Short Description Better readability, comprehensibility Sourcecode is for humans ! Bytecode for the machines. Some developers are proud of their cryptic code. Some developers think they write the code only for themself. To maintain, reuse or extend a programm the code must be understood before from the programmer. Agile Software Development Lab Spring 2008 ROOTS
9 Short Description Better readability, comprehensibility Sourcecode is for humans ! Bytecode for the machines. Some developers are proud of their cryptic code. Some developers think they write the code only for themself. To maintain, reuse or extend a programm the code must be understood before from the programmer. We want to make good software not good documentationpapers. To understand what the code does it must be good comprehensible. Comprehesible code doesn't need to be documented comprehensive. - Agile Software Development Lab Spring 2008 ROOTS
10 Short Description Better design Beginning with minimal or comprehensive Design Agile Software Development Lab Spring 2008 ROOTS
11 Short Description Better design Beginning with minimal or comprehensive Design Minimal (like in XP): Design grows with the Code. To get a good design we need to refactor. Agile Software Development Lab Spring 2008 ROOTS
12 Short Description Better design Beginning with minimal or comprehensive Design Minimal (like in XP): Design grows with the Code. To get a good design we need to refactor. Given Design (Traditional SE): Good Design is given before coding begins. Nice. But with evolution the design changes. Maybe then it is not more good. Agile Software Development Lab Spring 2008 ROOTS
13 Short Description Better design Beginning with minimal or comprehensive Design Minimal (like in XP): Design grows with the Code. To get a good design we need to refactor. Given Design (Traditional SE): Good Design is given before coding begins. Nice. But with evolution the design changes. Maybe then it is not more good. What to do to keep the good design ? Agile Software Development Lab Spring 2008 ROOTS
14 Short Description Better design Beginning with minimal or comprehensive Design Minimal (like in XP): Design grows with the Code. To get a good design we need to refactor. Given Design (Traditional SE): Good Design is given before coding begins. Nice. But with evolution the design changes. Maybe then it is not more good. What to do to keep the good design ? Refactor after or before all changes. Yippiyeah Agile Software Development Lab Spring 2008 ROOTS
15 Short Description Better maintainability and reusability Maintainability and Reusability: Changing any behaviour or adding new functionalities become much easier tasks if you understood the code fast and when the design is good. Agile Software Development Lab Spring 2008 ROOTS
16 Short Description Better maintainability and reusability Maintainability and Reusability: Changing any behaviour or adding new functionalities become much easier tasks if you understood the code fast and when the design is good. Important: When a feature has to be added to a program, if the code is not structured in a convenient way to add the feature, first refactor the program to make it easy to add the feature, then add the feature. Agile Software Development Lab Spring 2008 ROOTS
17 Precondition Question: Is there anything we have to do before and after a refactoring step ? Agile Software Development Lab Spring 2008 ROOTS
18 Precondition YES ! Agile Software Development Lab Spring 2008 ROOTS
19 Precondition Regressiontests: To be sure that you don't change the behavior of the code make tests after every refactoring. Before starting refactoring, it is important to have a solid test suite, with self-checking test cases. In fact, after refactoring the program, it is convenient to perform regression testing automatically, relying on its output to gain some confidence that bugs have not been introduced. Agile Software Development Lab Spring 2008 ROOTS
20 Precondition Question: Should we make big or many refactorings in a single step ? Agile Software Development Lab Spring 2008 ROOTS
21 Precondition NO ! Agile Software Development Lab Spring 2008 ROOTS
22 Precondition We should make little iterations. 1. Test 2. little refactoring step 3. Test 4. Add a feature 5. Test 6. little refactoring step 7. Test and so on. . . Agile Software Development Lab Spring 2008 ROOTS
23 Precondition We should make little iterations. 1. Test 2. little refactoring step 3. Test 4. Add a feature 5. Test 6. little refactoring step 7. Test and so on. . . Why is this important ? Agile Software Development Lab Spring 2008 ROOTS
24 Precondition We should make little iterations. 1. Test 2. little refactoring step 3. Test 4. Add a feature 5. Test 6. little refactoring step 7. Test and so on. . . Why is this important ? Thats important because if the test fails you don't have to search a long time the bug. Agile Software Development Lab Spring 2008 ROOTS
25 Checklist Simple Design! In priority order, the code must: • • Run all the tests Contain no duplicate code Express all the ideas the author wants to express Minimize classes and methods (Kent Beck) Agile Software Development Lab Spring 2008 • • Run all the tests Follow the once and only once rule Has high cohesion (clarity) Has loose coupling (Alan Shalloway) ROOTS
26 Steps for improvement Customer invoice() 1 Rental * get. Days. Rented() get. Movie() get. Charge() get. Frequent. Renter. Points() * Movie 1 get. Price. Code() set. Price. Code() get. Title() 4 Eliminating temporary variables 4 Splitting the invoice()-method 4 Moving subroutines to appropriate classes Replacing the pricecode dependentswitch-statements with message è Moving the method è Apply the Strategy pattern Agile Software Development Lab Spring 2008 ROOTS
27 Moving the charge()-method from Rental to Movie: Prior 1 Customer invoice() Rental * get. Days. Rented() get. Movie() get. Charge() get. Frequent. Renter. Points( * Movie 1 get. Price. Code() set. Price. Code() get. Title() getcharge() class Rental . . . public double getcharge() { double result = 0; switch (get. Movie(). get. Price. Code()) { case Movie. REGULAR: result += 2; if (get. Days. Rented() > 2) result += (get. Days. Rented()-2)*1. 5; break; case Movie. NEW_RELEASE: result +=get. Days. Rented()*3; break; case Movie. CHILDRENS: result += 1. 5; if (get. Days. Rented() > 3) result += (get. Days. Rented()-3)*1. 5; break; } } Agile Software Development Lab Spring 2008 ROOTS
28 Moving the charge()-method from Rental to Movie: 1 * Customer Rental Afterwards invoice() * get. Days. Rented() get. Movie() get. Charge() get. Frequent. Renter. Points( 1 Movie get. Price. Code() set. Price. Code() get. Title() get. Charge() class Movie . . . public double get. Charge(int days. Rented) { double result = 0; switch ( get. Price. Code()) { case Movie. REGULAR: result += 2; if ( days. Rented > 2) result += ( days. Rented -2)*1. 5; break; case Movie. NEW_RELEASE: result += days. Rented *3; break; case Movie. CHILDRENS: result += 1. 5; if ( days. Rented > 3) result += ( days. Rented -3)*1. 5; break; } } class Rental. . . public double get. Charge() { return _movie. charge(_days. Rented ); } Agile Software Development Lab Spring 2008 ROOTS
29 Moving bonus. Points()-method from Rental to Movie Customer invoice() 1 Rental * * get. Days. Rented() get. Movie() get. Charge() get. Frequent. Renter. Points() class Movie. . . public int get. Frequent. Renter. Points(int days. Rented) { if ( (this. get. Price. Code()==NEW_RELEASE ) && days. Rented>1) return 2; else return 1; } 1 Movie get. Price. Code() set. Price. Code() get. Title() get. Charge() get. Frequent. Renter. Points() class Rental. . . public int get. Frequent. Renter. Points() { if ((get. Movie(). get. Price. Code()==Movie. NEW_RELEASE ) && get. Days. Rented()>1) return 2; else return 1; } class Rental. . . public int get. Frequent. Renter. Points() { return _movie. get. Frequent. Renter. Points (_days. Rented); } Agile Software Development Lab Spring 2008 ROOTS
30 Polymorphism(from the Greek, meaning “many forms”) is a feature that allows one interface to be used for a general class of actions Agile Software Development Lab Spring 2008 ROOTS
31 Polymorphism via Inheritance Not applicable here: A movie would always have a fixed pricecategory Customer Rental 1 total. Charge() total. Bonus. Points() invoice. As. Html() days. Rented: int * charge() bonus. Points () Childrens. Price get. Charge(days: int) Agile Software Development Lab Spring 2008 Movie * 1 price. Code: int get. Price. Code() set. Price. Code() get. Charge(days: int) get. Frequent. Renter. Points(days: int) New. Release. Price get. Charge(days: int) get. Frequent. Renter. Points(days: int) Regular. Price get. Charge(days: int) ROOTS
32 Polymorphism via State Pattern Customer Rental 1 invoice() – total. Charge() – total. Bonus. Points() invoice. As. Html() – days. Rented: int * Movie * get. Days. Rented(): int get. Movie(): Movie charge() bonus. Points () charge(days: int) { return price. charge(days) } Childrens. Price get. Price. Code() getcharge(days: int) Agile Software Development Lab Spring 2008 1 – price. Code: int get. Price. Code() set. Price. Code() charge(days: int) bonus. Points(days: int) Price * 1 New. Release. Price get. Price. Code() getcharge(days: int) get. Frequent. Renter. Points(days: int) – price. Code: int get. Price. Code() charge(days: int) get. Fr. . . Points(days: int) Regular. Price get. Price. Code() getcharge(days: int) ROOTS
33 Polymorphismus via State Pattern Steps 1. Create classes Price, …, Regular. Price 2. Implement get. Price. Code()-methods therein 3. Replace the pricecode with a Price objekt (in Movie) u set. Price. Code(int) u get. Price. Code u Construktor Movie – price. Code: int get. Price. Code() set. Price. Code() get. Charge(days: int) get. Fr. . Points(days: int) Price * 1 – price. Code: int get. Price. Code() get. Charge(days: int) get. Fr. . (days: int) 4. Move charge() und bonus. Points() from Movie to Price 5. Replace switch-statements with polymorphism u Move each occurance of the charge() method from Price to the charge()method of a subclass u Analogous for bonus. Points() Agile Software Development Lab Spring 2008 New. Release. Price get. Price. Code() get. Charge(days: int) get. Fr. . . Points(days: int) Regular. Price get. Price. Code() get. Charge(days: int) ROOTS
34 Steps 1 -3: Replacement of pricecode with Price object class Movie {. . . private int _price. Code; class Movie. . . private Price _price; public Movie(String name, int price. Code) { _name = name; _price. Code = price. Code; } 3 public int get. Price. Code() { return _price. Code; } public void set. Price. Code(int arg) { _price. Code = arg; } } public Movie(String name, int price. Code) { _name = name; set. Price. Code(price. Code); } public int get. Price. Code() { return _price. get. Price. Code(); } public void set. Price. Code(int arg) { switch (arg) { case REGULAR: _price = new Regular. Price(); break; case CHILDRENS: _price = new Childrens. Price(); break; case NEW_RELEASE: _price = new New. Release. Price(); break; default: throw new Illegal. Argument. Exception ( “Incorrect price code“); } } } 1+2 abstract class Price { public abstract int get. Price. Code(); } class Regular. Price extends Price { public int get. Price. Code() { return Movie. REGULAR; } } class Childrens. Price extends Price { public int get. Price. Code() { return Movie. CHILDRENS; } } class New. Release. Price extends Price { public int get. Price. Code() { return Movie. NEW_RELEASE; } } Agile Software Development Lab Spring 2008 ROOTS
35 Steps 4 -5: Replace Switch with Polymorphism class Movie {. . . public double charge(int days. Rented) { return _price. charge(days. Rented); } 4 class Price {. . . public double get. Charge(int days. Rented) { double result = 0; switch (get. Price. Code()) { 5 case Movie. REGULAR: result += 2; if (days. Rented() > 2) result += (days. Rented()-2)*1. 5; break; case Movie. CHILDRENS: result += 1. 5; if (days. Rented() > 3) result += ( days. Rented()-3)*1. 5; break; case Movie. NEW_RELEASE: result +=days. Rented()*3; break; } } abstract class Price. . . abstract public double get. Charge(int days); class Regular. Price extends Price {. . . public double get. Charge(int days. Rented){ double result =2; if (days. Rented > 2) result += (days. Rented -2)*1. 5; return result; } class Childrens. Price extends Price {. . . public double get. Charge (int days. Rented){ double result = 1. 5; if (days. Rented > 3) result += (days. Rented -3) * 1. 5; return result; } class New. Release. Price extends Price {. . . public double get. Charge (int days. Rented) { return days. Rented * 3; } Agile Software Development Lab Spring 2008 ROOTS
36 The same for get. Frequent. Renter. Points class Rental. . . int get. Frequent. Rented. Points(int days. Rented) { if ((get. Price. Code() == Movie. NEW_RELEASE) && days. Rented > 1) return 2; else return 1; } class Rental. . . int get. Frequent. Rented. Points (int days. Rented) { return _movie. bonus. Points(days. Rented ); } class Movie. . . int get. Frequent. Renteroints(int days. Rented) { return _price. get. Frequent. Points(days. Rented); } class Price. . . int get. Frequent. Renteroints (int days. Rented) { return 1; } class New. Release. Price. . . int get. Frequent. Renteroints (int days. Rented) { return (days. Rented > 1) ? 2: 1; } Agile Software Development Lab Spring 2008 ROOTS
37 Extreme Code Quality Agile Software Development Lab Spring 2008 ROOTS
38 Benefits of refactoring 1. Improved Design 2. Better understanding of the code 3. Better bug detection 4. Faster development! Agile Software Development Lab Spring 2008 ROOTS
39 Simplicity is Code Quality Everything we write must n n Run all the tests Express every idea that we need to express Say everything once and only once Have the minimum number of classes and methods consistent with the above (Ron Jeffries et al. : Extreme Programming Installed) Agile Software Development Lab Spring 2008 ROOTS
40 Bad Smells In the community of computer programming, code smell is any symptom that indicates something may be wrong. It generally indicates that the code should be refactored or the overall design should be reexamined. The term appears to have been coined by Kent Beck on Wards. Wiki. Different Kinds of Bad Smells u u u Duplicated code Long Method Large Class Switch Statements Temporary Field …. Bad Smells in Code by Kent Beck and Martin Fowler Agile Software Development Lab Spring 2008 ROOTS
41 Refactoring-Catalog è Composition of Methodes u Extract Method u Inline Method u Replace Temp with Query u Inline Temp u Split Temporary Variable u Remove Assignments to Parameters u Replace Method with Method Object u. . . Agile Software Development Lab Spring 2008 ROOTS
42 Extract Method How to indicate? u Code-Blocks that are logically related to each other How to handle? u Replace with a well-named methode. void print. Owing(double amount) { print. Banner(); // print details System. out. println(“name“+_name); System. out. println(“amount“+ amount); } void print. Owing (double amount) { print. Banner(); print. Details(amount); } void print. Details (double amount) { System. out. println (“name“+_name); System. out. println (“amount“+ amount); } Agile Software Development Lab Spring 2008 ROOTS
43 Steps Defining new and well-named methodes u always „private“ Copy the Code Searching for the local variables in extracted code u Variables that will be used just in new methodes è local variables of new methodes u Variables which are changed in new methodes and will be used in old methodes è If only one: give it back as the result of new method è more than one: Parts that can not be extracted! („Replace Temp with Query“ or try to „Split Temp Variable“) u Variables that will be read in new methodes è Parameters of new methodes Agile Software Development Lab Spring 2008 ROOTS
44 Steps(2) Compiling in original methode u Replacing the extracted code by calling the new methode u Deleting of the delclaration of local variables which have use anymore Compiling Testing Agile Software Development Lab Spring 2008 ROOTS
45 Example: no local variables void print. Owing(double amount) { Enumeration e = : orders. elements(); double outstanding = 0. 0; // print banner System. out. println("***********"); System. out. println("*** Customer owes ****"); System. out. println("***********"); // calculate outstanding while (e. has. More. Elements()) { Order each = (Order) e. next. Element(); outstanding += each. get. Amount(); // print details System. out. println(“name“+ _name); System. out. println(“amount“+ outstanding); } è Extraction of code for print banner Agile Software Development Lab Spring 2008 ROOTS
46 Example: no local variables void print. Owing(double amount) { Enumeration e = : orders. elements(); double outstanding = 0. 0; print. Banner(); private void print. Banner() { System. out. println("***********"); System. out. println("*** Customer owes ****"); System. out. println("***********"); } // calculate outstanding while (e. has. More. Elements()) { Order each = (Order) e. next. Element(); outstanding += each. get. Amount(); // print details System. out. println(“name“+ _name); System. out. println(“amount“+ outstanding); } è Extraction of code for print banner u Local variable which is not altered („outstanding“) Agile Software Development Lab Spring 2008 ROOTS
47 Local variable which is not altered void print. Owing(double amount) { Enumeration e = : orders. elements(); double outstanding = 0. 0; print. Banner(); // calculate outstanding while (e. has. More. Elements()) { Order each = (Order) e. next. Element(); outstanding += each. get. Amount(); print. Details(outstanding); } private void print. Details(double outstanding) { System. out. println(“name“+ _name); System. out. println(“amount“+ outstanding); } è Extraction of codes for calculation u Local variable , which will be altered and finally used(„outstanding“) u Local variable , which will be altered and will not be used anymore „e“ Agile Software Development Lab Spring 2008 ROOTS
48 Example: Local variable wchich will be altered void print. Owing(double amount) { Enumeration e = : orders. elements(); double outstanding = 0. 0; print. Banner(); outstanding = get. Outstanding(); print. Details(outstanding); } private double get. Outstanding() { Enumeration e = orders. elements(); double outstanding = 0. 0; while (e. has. More. Elements()) { Order each = (Order) e. next. Element(); outstanding += each. get. Amount(); } return outstanding; } è Extracting code for calculation u If local variable is assigned before in original method Agile Software Development Lab Spring 2008 ROOTS
49 Exapmle : local variable that was altered even before void print. Owing(double amount) { double outstanding = amount *1. 2; print. Banner(); outstanding = get. Outstanding(outstanding); private double get. Outstanding(double start. Value) { Enumeration e = orders. elements(); double result = start. Value; print. Details(outstanding); while (e. has. More. Elements()) { Order each = (Order) e. next. Element(); result += each. get. Amount(); } } return result; } è Now are more Rafactorings possible u twice „inline temp“ for assigning to local variable „outstanding“ è In this way we can eliminate „outstanding“ from „print. Owing“-Methode Agile Software Development Lab Spring 2008 ROOTS
50 Example: Elimination of „outstanding“ void print. Owing(double amount) { double outstanding = amount *1. 2; print. Banner(); outstanding = get. Outstanding(outstanding); print. Details(outstanding); } Agile Software Development Lab Spring 2008 ROOTS
51 Example : End state of print. Owing() void print. Owing(double amount) { print. Banner(); print. Details(get. Outstanding(amount *1. 2)); } Agile Software Development Lab Spring 2008 ROOTS
52 Overview Refactoring Tools Commercial Together since Version 5. 5 Free Smalltalk Refactoring Browser u Only a few refactorings u www. togethersoft. com j. Factor u Plug-in for JBuilder and Visual. Age for Java u Extensive functionality u www. instantiations. com/jfactor/ IDEA u www. intellij. com/idea/ u IDE with builtin refactorings JBuilder since version 6 u Not tested yet Retool u New u www. chive. com Agile Software Development Lab Spring 2008 u First tool at all u Very powerfull u http: //chip. cs. uiuc. edu/users/brant/Refactory/ Xrefactory u Plug-in for Emacs u http: //www. xref-tech. com/speller Java. Refactor u Plug-in for j. Edit u http: //plugins. jedit. org/plugins/Java. Refactor Eclipse IDE u Preview, Veto and Undo of changes u Extract Method, Rename Method, . . . u www. eclipse. org ROOTS
53 Refrences Slides of SWT Lecture (Günter Kniesel) Slides of Exterme Programming for Nanjing Univesity(Günter Kniesel) Osborne - Java 2 --Complete Reference (5 th Ed 2002) Exapmles of Kent Beck and Martin Fowler From Berkley University http: //www. berkeley. edu/ http: //sis 36. berkeley. edu/projects/streek/agile/bad-smells-in-code. html Agile Software Development Lab Spring 2008 ROOTS
- Exterme programming
- Extreme wide shot definition
- Extreme programming
- History of extreme programming
- Extreme programming in software engineering
- Extreme programming agile
- Programming
- Extreme programming life cycle
- Diane pozefsky
- Extreme programming workflow
- Extreme point theorem linear programming
- Extreme programming advantages
- Extreme programming
- Alistair dilbert
- Ventajas y desventajas de la metodologia xp
- Extreme programming
- User requirements are expressed as in extreme programming
- Refactoring to patterns joshua kerievsky
- Refactoring vs shimming
- Refactoring
- Software refactoring beratung
- Refactoring: improving the design of existing code
- Code refactoring
- Refactoring and restructuring methods
- A survey of software refactoring
- Perbedaan linear programming dan integer programming
- Greedy vs dynamic programming
- Windows 10 system programming, part 1
- Integer programming vs linear programming
- Definisi linear
- A typical programming tasks can be divided into two phases
- Introduction to server side programming
- Problem solving
- Introduction to programming languages
- Elementary programming in java
- An introduction to parallel programming peter pacheco
- Introduction to visual basic programming
- What does plc stand for? *
- Java an introduction to problem solving and programming
- Console programming
- Programming language
- Cpe102/csc102 introduction to programming
- A web based introduction to programming
- System software: an introduction to systems programming
- Computer programming chapter 1
- C programming and numerical analysis an introduction
- Introduction to visual basic
- Introduction to programming concepts with scratch
- Python programming an introduction to computer science
- Java introduction to problem solving and programming
- Chapter 1 introduction to computers and programming
- Introduction to java programming 10th edition quizzes
- Introduction to sql programming techniques
- Introduction to sql programming techniques