agile software development lab spring 2008 r o o t s 1 sina golesorkhi([email protected])...

53
Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi([email protected]) Thomas Schmickler([email protected] bonn.de) XP: Extreme Programming Introduction into Refactoring, Refactoring to Patterns and Code Q Refactoring

Upload: ruby-turner

Post on 04-Jan-2016

214 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

1

Sina Golesorkhi([email protected])Thomas Schmickler([email protected])

XP: Extreme ProgrammingIntroduction into Refactoring, Refactoring to Patterns and Code Quality

Refactoring

Page 2: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

2

Overview

Definition An Example in Eclipse Short Description Precondition of Refactoring Checklist Advantages of Refactoring Indicators for Refactoring are called „Bad Smells“

Page 3: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

3

DefintionWhat is Refactoring ?

Refactor (verb): to restructure software by applying a series of refactorings.

Goals:

• Better readability, comprehensibility• Better design• Better maintainability and reusability

Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing ist observable behavior.

Page 4: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

4

Example in Eclipse

You can download the code from http://www.schmickler.de/code.zip

Page 5: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

5

Short Description Better readability, comprehensibility

Sourcecode is for humans ! Bytecode for the machines.

Page 6: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

6

Short Description Better readability, comprehensibility

Sourcecode is for humans ! Bytecode for the machines.

Some developers are proud of their cryptic code.

Page 7: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

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.

Page 8: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

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.

Page 9: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

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.

Page 10: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

10

Short Description Better design

Beginning with minimal or comprehensive Design

Page 11: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

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.

Page 12: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

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.

Page 13: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

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 ?

Page 14: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

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

Page 15: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

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 codefast and when the design is good.

Page 16: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

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 codefast and when the design is good.

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.

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.

Important:

Page 17: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

17

Precondition

Is there anything we have to do before and after a refactoring step ?

Question:

Page 18: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

18

Precondition

YES !

Page 19: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

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.

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.

Page 20: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

20

Precondition

Should we make big or many refactorings in a single step ?

Question:

Page 21: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

21

Precondition

NO !

Page 22: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

22

Precondition

We should make little iterations.

1. Test2. little refactoring step3. Test4. Add a feature5. Test6. little refactoring step7. Test

and so on...

Page 23: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

23

Precondition

We should make little iterations.

1. Test2. little refactoring step3. Test4. Add a feature5. Test6. little refactoring step7. Test

and so on...

Why is this important ?

Page 24: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

24

Precondition

We should make little iterations.

1. Test2. little refactoring step3. Test4. Add a feature5. Test6. little refactoring step7. Test

and so on...

Thats important because if the test fails you don't have to search a long timethe bug.

Why is this important ?

Page 25: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

25

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)

• Run all the tests • Follow the once and

only once rule• Has high cohesion

(clarity) • Has loose coupling

(Alan Shalloway)

Checklist

Page 26: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

26

Steps for improvement

Eliminating temporary variables

Splitting the invoice()-method

Moving subroutines to appropriate classes

Replacing the pricecode dependentswitch-statements with message Moving the method Apply the Strategy pattern

MoviegetPriceCode()setPriceCode()getTitle()

1

1*

*Customerinvoice()

RentalgetDaysRented()getMovie()getCharge()getFrequentRenterPoints()

Page 27: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

27

Moving the charge()-method from Rental to Movie: Prior

class Rental ... public double getcharge() {

double result = 0;switch (getMovie().getPriceCode()) {

case Movie.REGULAR: result += 2;if (getDaysRented() > 2)

result += (getDaysRented()-2)*1.5;break;

case Movie.NEW_RELEASE:result +=getDaysRented()*3;break;

case Movie.CHILDRENS:result += 1.5;if (getDaysRented() > 3)

result += (getDaysRented()-3)*1.5;break;

}}

class Rental ... public double getcharge() {

double result = 0;switch (getMovie().getPriceCode()) {

case Movie.REGULAR: result += 2;if (getDaysRented() > 2)

result += (getDaysRented()-2)*1.5;break;

case Movie.NEW_RELEASE:result +=getDaysRented()*3;break;

case Movie.CHILDRENS:result += 1.5;if (getDaysRented() > 3)

result += (getDaysRented()-3)*1.5;break;

}}

Movie

getPriceCode()setPriceCode()getTitle()getcharge()

1

1*

*Customer

invoice()

Rental

getDaysRented()getMovie()getCharge()getFrequentRenterPoints(

Page 28: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

28

Moving the charge()-method from Rental to Movie: Afterwards

class Movie ... public double getCharge(int daysRented) {

double result = 0;switch ( getPriceCode()) {

case Movie.REGULAR: result += 2;if ( daysRented > 2)

result += ( daysRented -2)*1.5;break;

case Movie.NEW_RELEASE:result += daysRented *3;break;

case Movie.CHILDRENS:result += 1.5;if ( daysRented > 3)

result += ( daysRented -3)*1.5;break;

}

}

class Movie ... public double getCharge(int daysRented) {

double result = 0;switch ( getPriceCode()) {

case Movie.REGULAR: result += 2;if ( daysRented > 2)

result += ( daysRented -2)*1.5;break;

case Movie.NEW_RELEASE:result += daysRented *3;break;

case Movie.CHILDRENS:result += 1.5;if ( daysRented > 3)

result += ( daysRented -3)*1.5;break;

}

}

class Rental ...public double getCharge() {

return _movie.charge(_daysRented);}

class Rental ...public double getCharge() {

return _movie.charge(_daysRented);}

MoviegetPriceCode()setPriceCode()getTitle()getCharge()

1

1*

*Customerinvoice()

RentalgetDaysRented()getMovie()getCharge()getFrequentRenterPoints(

Page 29: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

29

Moving bonusPoints()-method from Rental to Movie

class Movie ...public int getFrequentRenterPoints(int daysRented) {

if ( (this.getPriceCode()==NEW_RELEASE) && daysRented>1)return 2;

elsereturn 1;

}

class Movie ...public int getFrequentRenterPoints(int daysRented) {

if ( (this.getPriceCode()==NEW_RELEASE) && daysRented>1)return 2;

elsereturn 1;

}

class Rental ...public int getFrequentRenterPoints() {

return _movie.getFrequentRenterPoints(_daysRented); }

class Rental ...public int getFrequentRenterPoints() {

return _movie.getFrequentRenterPoints(_daysRented); }

class Rental ...public int getFrequentRenterPoints() {

if ((getMovie().getPriceCode()==Movie.NEW_RELEASE) && getDaysRented()>1)

return 2;else

return 1;}

class Rental ...public int getFrequentRenterPoints() {

if ((getMovie().getPriceCode()==Movie.NEW_RELEASE) && getDaysRented()>1)

return 2;else

return 1;}

MoviegetPriceCode()setPriceCode()getTitle()getCharge()getFrequentRenterPoints()

1

1*

*Customerinvoice()

RentalgetDaysRented()getMovie()getCharge()getFrequentRenterPoints()

Page 30: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

30

Polymorphism

Polymorphism(from the Greek, meaning “many forms”) is a feature that allows one interface to be used for a general class of actions

Page 31: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

31

ChildrensPrice NewReleasePrice RegularPrice

Polymorphism via Inheritance

Movie

priceCode:int

getPriceCode()setPriceCode()getCharge(days:int)getFrequentRenterPoints(days:int)

1

1Customer

totalCharge()totalBonusPoints()invoice()invoiceAsHtml()

*

*

Rental

daysRented:int

charge()bonusPoints ()

getCharge(days:int) getCharge(days:int) getFrequentRenterPoints(days:int)

getCharge(days:int)

Not applicable here: A movie would always have a fixed pricecategory

Page 32: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

32

Polymorphism via State Pattern

Movie

– priceCode:int

getPriceCode()setPriceCode()charge(days:int)bonusPoints(days:int)

ChildrensPrice

getPriceCode()getcharge(days:int)

NewReleasePrice

getPriceCode() getcharge(days:int)getFrequentRenterPoints(days:int)

RegularPrice

getPriceCode()getcharge(days:int)

Price

– priceCode:int

getPriceCode()

charge(days:int)getFr...Points(days:int)

1

*

1

1Customer

invoice()– totalCharge()– totalBonusPoints()invoiceAsHtml()

*

*

Rental

– daysRented:int

getDaysRented():intgetMovie():Moviecharge()bonusPoints ()

charge(days:int) { return price.charge(days)}

Page 33: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

33

Polymorphismus via State Pattern

Movie

– priceCode:int

getPriceCode()setPriceCode()getCharge(days:int)getFr..Points(days:int)

NewReleasePrice

getPriceCode()getCharge(days:int)getFr...Points(days:int)

RegularPrice

getPriceCode()getCharge(days:int)

Price

– priceCode:int

getPriceCode()

getCharge(days:int)getFr..(days:int)

1

*

Steps

1. Create classes Price, …, RegularPrice

2. Implement getPriceCode()-methods therein

3. Replace the pricecode with a Price objekt (in Movie) setPriceCode(int) getPriceCode Construktor

4. Move charge() und bonusPoints() from Movie to Price

5. Replace switch-statements with polymorphism Move each occurance of the charge()

method from Price to the charge()-method of a subclass

Analogous for bonusPoints()

Page 34: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

34

Steps 1-3: Replacement of pricecode with Price object

class Movie { ... private int _priceCode;

public Movie(String name, int priceCode) {_name = name;_priceCode = priceCode;

}public int getPriceCode() {

return _priceCode;}public void setPriceCode(int arg) {

_priceCode = arg; }}

class Movie { ... private int _priceCode;

public Movie(String name, int priceCode) {_name = name;_priceCode = priceCode;

}public int getPriceCode() {

return _priceCode;}public void setPriceCode(int arg) {

_priceCode = arg; }}

3

abstract class Price {public abstract int getPriceCode();

}

abstract class Price {public abstract int getPriceCode();

}class RegularPrice extends Price {

public int getPriceCode() { return Movie.REGULAR;}

}

class RegularPrice extends Price {public int getPriceCode() { return Movie.REGULAR;}

}class ChildrensPrice extends Price {

public int getPriceCode() { return Movie.CHILDRENS;}

}

class ChildrensPrice extends Price {public int getPriceCode() { return Movie.CHILDRENS;}

}class NewReleasePrice extends Price {

public int getPriceCode() { return Movie.NEW_RELEASE;}

}

class NewReleasePrice extends Price {public int getPriceCode() { return Movie.NEW_RELEASE;}

}

1+2

class Movie ...private Price _price;

public void setPriceCode(int arg) {switch (arg) {

case REGULAR:_price = new RegularPrice();break;

case CHILDRENS:_price = new ChildrensPrice();break;

case NEW_RELEASE:_price = new NewReleasePrice();break;

default:throw new

IllegalArgumentException( “Incorrect price code“);

}}

}

public Movie(String name, int priceCode) {_name = name;setPriceCode(priceCode);

}public int getPriceCode() {

return _price.getPriceCode();}

Page 35: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

35

class Price { ... public double getCharge(int daysRented) {

double result = 0; switch (getPriceCode()) {

case Movie.REGULAR:result += 2;if (daysRented() > 2)

result += (daysRented()-2)*1.5;break;

case Movie.CHILDRENS:result += 1.5;if (daysRented() > 3)

result += ( daysRented()-3)*1.5;break;

case Movie.NEW_RELEASE:result +=daysRented()*3;break;

} }

class Price { ... public double getCharge(int daysRented) {

double result = 0; switch (getPriceCode()) {

case Movie.REGULAR:result += 2;if (daysRented() > 2)

result += (daysRented()-2)*1.5;break;

case Movie.CHILDRENS:result += 1.5;if (daysRented() > 3)

result += ( daysRented()-3)*1.5;break;

case Movie.NEW_RELEASE:result +=daysRented()*3;break;

} }

Steps 4-5: Replace Switch with Polymorphism

abstract class Price ...abstract public double getCharge(int days);

abstract class Price ...abstract public double getCharge(int days);

class RegularPrice extends Price { ...public double getCharge(int daysRented)

{ double result =2;if (daysRented > 2)

result += (daysRented -2)*1.5;return result;

}

class RegularPrice extends Price { ...public double getCharge(int daysRented)

{ double result =2;if (daysRented > 2)

result += (daysRented -2)*1.5;return result;

}

class ChildrensPrice extends Price { ...public double getCharge (int

daysRented){double result = 1.5;if (daysRented > 3)

result += (daysRented -3) * 1.5;return result;

}

class ChildrensPrice extends Price { ...public double getCharge (int

daysRented){double result = 1.5;if (daysRented > 3)

result += (daysRented -3) * 1.5;return result;

}

class NewReleasePrice extends Price { ...public double getCharge (int daysRented)

{return daysRented * 3;

}

class NewReleasePrice extends Price { ...public double getCharge (int daysRented)

{return daysRented * 3;

}

class Movie { ... public double charge(int daysRented) { return _price.charge(daysRented); }

class Movie { ... public double charge(int daysRented) { return _price.charge(daysRented); }

4

5

Page 36: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

36

The same for getFrequentRenterPoints

class Rental...int getFrequentRentedPoints(int daysRented) {

if ((getPriceCode() == Movie.NEW_RELEASE) && daysRented > 1)return 2;

elsereturn 1;

}

class Rental...int getFrequentRentedPoints(int daysRented) {

if ((getPriceCode() == Movie.NEW_RELEASE) && daysRented > 1)return 2;

elsereturn 1;

}

class NewReleasePrice...int getFrequentRenteroints (int daysRented) {

return (daysRented > 1) ? 2: 1; }

class NewReleasePrice...int getFrequentRenteroints (int daysRented) {

return (daysRented > 1) ? 2: 1; }

class Rental...int getFrequentRentedPoints (int daysRented) {

return _movie.bonusPoints(daysRented); }

class Rental...int getFrequentRentedPoints (int daysRented) {

return _movie.bonusPoints(daysRented); }

class Movie...int getFrequentRenteroints(int daysRented) {

return _price.getFrequentPoints(daysRented); }

class Movie...int getFrequentRenteroints(int daysRented) {

return _price.getFrequentPoints(daysRented); }

class Price...int getFrequentRenteroints (int daysRented) {

return 1; }

class Price...int getFrequentRenteroints (int daysRented) {

return 1; }

Page 37: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

37

Extreme Code Quality

Page 38: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

38

Benefits of refactoring

1. Improved Design

2. Better understanding of the code

3. Better bug detection

4. Faster development!

Page 39: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

39

Simplicity is Code Quality

Everything we write must

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)

Page 40: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

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

Different Kinds of Bad Smells Duplicated code Long Method Large Class Switch Statements Temporary Field ….

Bad Smells in Code by Kent Beck and Martin Fowler

Page 41: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

41

Refactoring-Catalog

Composition of Methodes Extract Method Inline Method Replace Temp with Query Inline Temp Split Temporary Variable Remove Assignments to Parameters Replace Method with Method Object ...

Page 42: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

42

Extract Method

void printOwing(double amount) {printBanner();

// print detailsSystem.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);

}

How to indicate? Code-Blocks that are logically related to each other

How to handle? Replace with a well-named methode .

Page 43: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

43

Steps Defining new and well-named methodes

always „private“

Copy the Code

Searching for the local variables in extracted code Variables that will be used just in new methodes

local variables of new methodes

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

Variables that will be read in new methodes Parameters of new methodes

Page 44: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

44

Steps(2)

Compiling

in original methode Replacing the extracted code by calling the new methode Deleting of the delclaration of local variables which have use anymore

Compiling Testing

Page 45: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

45

Example: no local variables

void printOwing(double amount) {

Enumeration e = :orders.elements();double outstanding = 0.0;

// print bannerSystem.out.println("**********************");System.out.println("*** Customer owes ****");System.out.println("**********************");

// calculate outstandingwhile (e.hasMoreElements()) {

Order each = (Order) e.nextElement();outstanding += each.getAmount();

// print detailsSystem.out.println(“name“+ _name);System.out.println(“amount“+ outstanding);

}

Extraction of code for print banner

Page 46: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

46

Example: no local variables

void printOwing(double amount) {

Enumeration e = :orders.elements();double outstanding = 0.0;

printBanner();

// calculate outstandingwhile (e.hasMoreElements()) {

Order each = (Order) e.nextElement();outstanding += each.getAmount();

// print detailsSystem.out.println(“name“+ _name);System.out.println(“amount“+ outstanding);

}

Extraction of code for print banner Local variable which is not altered („outstanding“)

private void printBanner() {System.out.println("**********************");System.out.println("*** Customer owes ****");System.out.println("**********************");

}

Page 47: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

47

Local variable which is not altered

void printOwing(double amount) {

Enumeration e = :orders.elements();double outstanding = 0.0;

printBanner();

// calculate outstandingwhile (e.hasMoreElements()) {

Order each = (Order) e.nextElement();outstanding += each.getAmount();

printDetails(outstanding);

}

Extraction of codes for calculation Local variable , which will be altered and finally used(„outstanding“) Local variable , which will be altered and will not be used anymore „e“

private void printDetails(double outstanding) {System.out.println(“name“+ _name);System.out.println(“amount“+ outstanding);

}

Page 48: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

48

Example:Local variable wchich will be altered

void printOwing(double amount) {

Enumeration e = :orders.elements();double outstanding = 0.0;

printBanner();

outstanding = getOutstanding();

printDetails(outstanding);

}

Extracting code for calculation If local variable is assigned before in original method

private double getOutstanding() {Enumeration e = orders.elements();double outstanding = 0.0;while (e.hasMoreElements()) {

Order each = (Order) e.nextElement();outstanding += each.getAmount();

}return outstanding;

}

Page 49: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

49

Exapmle : local variable that was altered even before

void printOwing(double amount) {

double outstanding = amount *1.2;

printBanner();

outstanding = getOutstanding(outstanding);

printDetails(outstanding);

}

private double getOutstanding(double startValue) {Enumeration e = orders.elements();double result = startValue;while (e.hasMoreElements()) {

Order each = (Order) e.nextElement();result += each.getAmount();

}return result;

}

Now are more Rafactorings possible twice „inline temp“ for assigning to local variable „outstanding“ In this way we can eliminate „outstanding“ from „printOwing“-Methode

Page 50: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

50

Example: Elimination of „outstanding“

void printOwing(double amount) {

double outstanding = amount *1.2;

printBanner();

outstanding = getOutstanding(outstanding);

printDetails(outstanding);

}

Page 51: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

51

Example : End state of printOwing()

void printOwing(double amount) {

printBanner();

printDetails(getOutstanding(amount *1.2));

}

Page 52: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

52

Overview Refactoring Tools

Commercial Together since Version 5.5

Only a few refactorings www.togethersoft.com

jFactor Plug-in for JBuilder and VisualAge

for Java Extensive functionality www.instantiations.com/jfactor/

IDEA www.intellij.com/idea/ IDE with builtin refactorings

JBuilder since version 6 Not tested yet

Retool New www.chive.com

Free Smalltalk Refactoring Browser

First tool at all Very powerfull http://chip.cs.uiuc.edu/users/brant/Refactory/

Xrefactory Plug-in for Emacs http://www.xref-tech.com/speller

JavaRefactor Plug-in for jEdit http://plugins.jedit.org/plugins/JavaRefactor

Eclipse IDE Preview, Veto and Undo of changes Extract Method, Rename Method, ... www.eclipse.org

Page 53: Agile Software Development Lab Spring 2008 R O O T S 1 Sina Golesorkhi(golesork@cs.uni-bonn.de) Thomas Schmickler(schmickl@cs.uni-bonn.de ) XP: Extreme

Agile Software Development Lab Spring 2008 R O O T S

53

Refrences

Slides of SWT Lecture (Günter Kniesel) Slides of Exterme Programming for Nanjing Univesity(Günter Kniesel) Osborne - Java 2--Complete Reference (5th Ed 2002) Exapmles of Kent Beck and Martin Fowler From Berkley University

http://www.berkeley.edu/ http://sis36.berkeley.edu/projects/streek/agile/bad-smells-in-code.html