1 XP Extreme Programming Introduction into Refactoring Refactoring

  • Slides: 53
Download presentation
1 XP: Extreme Programming Introduction into Refactoring, Refactoring to Patterns and Code Quality Refactoring

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

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

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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

21 Precondition NO ! Agile Software Development Lab Spring 2008 ROOTS

22 Precondition We should make little iterations. 1. Test 2. little refactoring step 3.

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.

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.

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

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()

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 *

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()

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 * *

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

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

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.

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.

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 {. .

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

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.

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

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.

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

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

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

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

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

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

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 = :

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 = :

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

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

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)

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

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.

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

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

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