9 refactoring refactoring changes the software structure but does not change the functionality of...

26
9 Refactoring • Refactoring changes the software structure but does not change the functionality of the program – important activity during evolution • Refactoring consists of behaviour preserving transformations – Fowler: Refactoring (book, web site) http://www.refactoring.com/ • Restructuring, reengineering © 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 1

Upload: carmel-fox

Post on 28-Dec-2015

219 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

9 Refactoring

• Refactoring changes the software structure but does not change the functionality of the program– important activity during evolution

• Refactoring consists of behaviour preserving transformations– Fowler: Refactoring (book, web site)

http://www.refactoring.com/

• Restructuring, reengineering© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 1

Page 2: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Two roles of refactoring

• Prefactoring– before attempting the

actualization• refactoring will make actualization

easier

• Postfactoring– prepares software for future

evolution– cleans up the code

Initiation

Concept Location

Impact Analysis

Prefactoring

Actualization

Postfactoring

ConclusionConclusion

VERIFICATION

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 2

Page 3: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Examples of refactoring

• Rename an entity

• Encapsulate part of the code as a function

– opposite: expand a function in a place of call

• Move function into/out of class

• Merge and divide classes

– factor out a base class, component class© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 3

Page 4: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Extract function

• During the software evolution some functions may grow to be too large

• Or we may need to separate two concepts the function currently deals with

• Extracting part of the function into another function will make it – easier to understand– reusable

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 4

Page 5: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

void foo(char c, int& count) {

int i,len;char str[MAX];cin>>str;len=strlen(str);count=0; for(i=0;i<len;i++)

if(str[i]==c) count++;

}

void foo(char c, int count&) {

int len; char str[MAX]; cin>>str; len=strlen(str); newfun(count,len,str,c);

}

void newfun(int& count,int len, char* str,char c) { int i; count=0; for(i=0;i<=len;i++)

if(str[i]==c) count++;

}

Extract function example

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 5

Page 6: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Extract function process

• Select a block of code for extraction

• Is the block syntactically complete?

• Create new function

• Extract the selected block as a function body

• Replace the code block with the function call

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 6

Page 7: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Variables during extract function

• Local variable– value assigned inside, used only inside

• Parameter passed by value– value assigned outside

• Parameter passed by reference – value assigned and used outside, changed

inside

• Global variable

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 7

Page 8: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Extract a base class

• In code development, derived classes always come before the base classes– developers may miss some base classes– refactoring will correct these omissions

• Extract a base class prepares software for incorporation of new functionality through polymorphism– applicable when old and new functionality

have a large overlap© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 8

Page 9: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Example

class Matrix{

protected:

int elements [10000], columns, rows;

public:

Matrix();

inverse();

matrix multiply (Matrix&);

int get (int,int);

void put(int,int);

}; // dense matrix

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 9

Page 10: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Extract class AbstractMatrix

• Change request: Add sparse matrix to the code.– sparse matrix uses the same algorithm for “multiply”

and “inverse”.– only access to the elements are different (functions

“get” and “put”)

• Extract abstract class AbstractMatrix– DenseMatrix and SparseMatrix will be derived from it– this will make the change (much) easier– it will allow to incorporate SparseMatrix through

polymorphism

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 10

Page 11: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Step 1 of refactoring

• Rename class

– class Matrix class DenseMatrix

• There will be several classes dealing with

matrix

– name needs to be more specific

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 11

Page 12: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

The next steps of refactoring and incorporation

2. Extracting base class 3. Incorporating SparseMatrix

DenseMatrix

AbstractMatrix

SparseMatrixDenseMatrix

AbstractMatrix

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 12

Page 13: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Steps of refactoring

• Create a new class AbstractMatrix• Make DenseMatrix derived from AbstractMatrix

• Replace all references to the elements by get and set

• Move variables columns and rows to AbstractMatrix

• Move functions inverse and multiply to AbstractMatrix

• Add virtual functions get and set into AbstractMatrix

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 13

Page 14: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Results

• After refactoring, it is easy to incorporate

SparseMatrix

• Refactoring preserves the behaviour

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 14

Page 15: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Component class extraction

• Motivation: Incorporation by replacement– primitive implementation of the class is

replaced by a full functionality

• Concept sometimes does not have class of its own– must be extracted from another class– prefactoring for incorporation by replacement

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 15

Page 16: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Example: Price in PoS

+getBalance() : double+processSale() : double+resetStore() : void+Main() : void

-balance : double-inventory : Inventory

Store

-inventory : ItemInventory

+getPrice():double+setPrice(double)+calcSubTotal() : double+calcTotal() : double

-upc : long-name : string-inventory : int-price : double-tax : double

Item

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 16

Page 17: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Refactoring

+getBalance() : double

-balance : double-inventory : inventory

Store-inventory : Item

inventory

+setPrice(double)+getPrice() : double+calcSubTotal() : double+calcTotal() : double

-upc : long-name : string-inventory : int-price : double-tax : double-price : Price

Item

+setPrice(double)+getPrice() : double

-price : doublePrice

-price:Price

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 17

Page 18: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Changes in class Item

public double calcSubTotal(int numberToSell) {

if (numberToSell < 1) return 0.0;

else

// return numberToSell * price;

return

numberToSell*price.getPrice();

}

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 18

Page 19: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Extract CashierRecord in PoS

+getCashierId()+getFirstName()+getLastName()+getLoggedIn()+getPassword()

-cashierId : string-firstName : string-lastName : string-loggedIn : string-password : string

CashierRecord

+Cashier(id : int, pw : string, fn : string, ln : string)+getCashierId()+getFirstName()+getLastName()+getLoggedIn()+getPassword()+setCashierRecord()+getCashierRecord()+login()+logout()+isLoggedIn()

-cashierId : string-firstName : string-lastName : string-loggedIn : string-password : string-cashierRecord : CashierRecord

Cashier

-cashier : CashierStore

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 19

Page 20: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Incorporation after prefactoring

Item

+getPrice() : double

-currentPrice : double-salePrice : double-date : Calendar

Price

Store Inventory

Price

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 20

Page 21: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Function insertion in C++

• A stand-alone function should be a

member of a class

• Function insertion will accomplish that

• Opposite: Function expulsion

– expels member function from a class

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 21

Page 22: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Example of function insertion

class A {public:

int i;protected:

char c;};

int foo(A& a) {a.i = 4;..

.}

int main() {A la;...foo(la)...}

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 22

Page 23: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Example of function insertion

class A {public:

int i;int foo();

protected: char c;

};

int A::foo() {this->i = 4;..

.}

int main() {A la;...la.foo()...}

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 23

Page 24: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Actions of function insertion

• The function’s header is inserted into the class specification.

• Change access to the members of the target class• The function header must be qualified by the class

identifier. • The parameter that is now replaced by membership

must be removed. • All function calls must be qualified with a class instance.• All forward declarations of the function are replaced by

the new function declaration in the target class specification.

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 24

Page 25: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

Move function from composite to component

class A { // A is composite

B* b; // B is component

};• Add a new parameter of the composite type to the

function• Access all component members through the new

parameter• Move the misplaced function from the composite

into the component

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 25

Page 26: 9 Refactoring Refactoring changes the software structure but does not change the functionality of the program –important activity during evolution Refactoring

class A {public: B* b; int a_data; void a_fun(); void foo();};

void A::a_fun() {this->foo();}

void A::foo(){//access Athis->...//access Bb->...}

class B {};

class A {public: B* b; int a_data; void a_fun(); void foo(B*);};

void A::a_fun() {this->foo(b);}

void A::foo(B* lb){//access Athis->...//access Blb->...}

class B {};

class A {public: B* b; int a_data; void a_fun();};

void A::a_fun(){b->foo(this);}

void B::foo(A* d){//accsess Ad->...//access Bthis->...}

class B {public: void foo(A*);};

Move function - example

© 2012 Václav Rajlich Software Engineering: The Current Practice Ch. 1 26