refactoring and its role in test-driven development miguel j. t. pessoa monteiro escola superior de...

49
Refactoring and its role in Test-Driven Development Miguel J. T. Pessoa Monteiro Escola Superior de Tecnologia de Castelo Branco

Upload: coral-cannon

Post on 31-Dec-2015

214 views

Category:

Documents


0 download

TRANSCRIPT

Refactoringand its role in

Test-Driven Development

Miguel J. T. Pessoa Monteiro

Escola Superior de Tecnologiade Castelo Branco

2

Overview

Characterisation of Refactoring Brief History of Refactoring Examples of refactoring steps How refactorings are performed When to refactor (code smells) Role of unit tests in refactoring Resources

3

Refactoring

Tenet of Refactoring Program source code

is a mechanism of communication between humans, not between the programmer and the computer.

4

public void add(Object element) {if(!readOnly) {

int newSize = size + 1;if(newSize > elements.length) {

Object[] newElements = new Object[elemnts.length + 10];for(int i=0; i<size; i++)

newElements[i] = elements[i];elements = newElements;

}elements[size++] = element;

}}

public void add(Object element) {if(readOnly)

return;if(atCapacity())

grow();addElement(element);

}

Intentionality is Important

5

Characterising Refactoring

Martin Fowler: “a disciplined technique for

restructuring an existing body of code, altering its internal structure without changing its external behaviour.”

6

Characterising Refactoring

Martin Fowler: “Each transformation does little, but a sequence of

transformations can produce a significant restructuring.

Since each refactoring is small, it's less likely to go wrong”.

7

The “Two Hat” Metaphor Programmer always wearing one of 2

hats: The developer hat The refactoring hat

If the task can be made easier if the code is structured differently,

Programmer swaps hats and refactors for a while.

Then he swaps hats again, and adds the functionality.

8

What is not Refactoring

Adding new functionalityis not refactoring

Optimisation is not refactoring Changing code that does not

compileis not refactoring(what would be the behaviour?)

9

Overview

Characterisation of Refactoring Brief History of Refactoring Examples of refactoring steps How refactorings are performed When to refactor (code smells) Role of unit tests in refactoring Resources

10

Brief History of Refactoring Griswold W., Program restructuring as an

aid to software maintenance. PhD thesis, University of Washington, USA, 1991.

Opdyke W., Refactoring Object-Oriented Frameworks, Ph.D. Thesis, University of Illinois at Urbana-Champaign, USA, 1992.

Roberts D., Brant J., Johnson R., A refactoring tool for smalltalk. Theory and Practice of Object Systems 3(4), pp. 253–263, 1997.

11

Brief History of Refactoring

Advent of unit tests (e.g. xUnit) Made manual refactoring possible.

Advent of Extreme Programming (XP) Test-driven development: Unit testing,

Refactoring, Pair programming, etc. Martin Fowler’s book

Promoted refactoring to buzzword status

12

Overview

Characterisation of Refactoring Brief History of Refactoring Examples of refactoring steps How refactorings are performed When to refactor (code smells) Role of unit tests in refactoring Resources

13

Reverse ConditionalYou have a conditional that would be easier to understand if you reversed its sense.

Reverse the sense of the conditional and reorder the conditional's clauses.

if ( !isSummer( date ) ) charge = winterCharge( quantity );else charge = summerCharge( quantity );

            

if ( isSummer( date ) ) charge = summerCharge( quantity );else charge = winterCharge( quantity );

14

Rename MethodThe name of a method does not reveal its purpose.Change the name of the method.

15

Move MethodA method is, or will be, (using or) used by more features of another class than the class on which it is defined.

Create a new method with a similar body in the class it uses most. Either turn the old method into a simple delegation, or remove it altogether.

16

Pull Up MethodYou have methods with identical results on subclasses.

Move them to the superclass.

17

Extract MethodYou have a code fragment that can be grouped together.

Turn the fragment into a method whose name explains the purpose of the method.

void printOwing() {printBanner();

//print detailsSystem.out.println ("name: " + _name);System.out.println ("amount " + getOutstanding());

}             

void printOwing() {printBanner();printDetails(getOutstanding());

}void printDetails (double outstanding) {

System.out.println ("name: " + _name);System.out.println ("amount " + outstanding);

}

18

Extract MethodYou have a code fragment that can be grouped together.

Turn the fragment into a method whose name explains the purpose of the method.

void printOwing() {printBanner();

//print detailsSystem.out.println ("name: " + _name);System.out.println ("amount " + getOutstanding());

}             

void printOwing() {printBanner();printDetails(getOutstanding());

}void printDetails (double outstanding) {

System.out.println ("name: " + _name);System.out.println ("amount " + outstanding);

}

19

Inline MethodA method's body is just as clear as its name.

Put the method's body into the body of its callers and remove the method.

int getRating() {return (moreThanFiveLateDeliveries()) ? 2 : 1;

}boolean moreThanFiveLateDeliveries() {

return _numberOfLateDeliveries > 5;}

int getRating() {return (_numberOfLateDeliveries > 5) ? 2 : 1;

}

20

Inline MethodA method's body is just as clear as its name.

Put the method's body into the body of its callers and remove the method.

int getRating() {return (moreThanFiveLateDeliveries()) ? 2 : 1;

}boolean moreThanFiveLateDeliveries() {

return _numberOfLateDeliveries > 5;}

int getRating() {return (_numberOfLateDeliveries > 5) ? 2 : 1;

}

Opposite to Extract Method

21

Replace Conditional with PolymorphismYou have a conditional that chooses different behavior depending on the type of an object.Move each leg of the conditional to an overriding method in a subclass. Make the original method abstract.

double getSpeed() { switch (_type) { case EUROPEAN: return getBaseSpeed(); case AFRICAN: return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts; case NORWEIGIAN_BLUE: return (_isNailed) ? 0 : getBaseSpeed(_voltage); } throw new RuntimeException ("Should be unreachable");}

22

Replace Conditional with PolymorphismYou have a conditional that chooses different behavior depending on the type of an object.Move each leg of the conditional to an overriding method in a subclass. Make the original method abstract.

23

Overview

• Characterisation of Refactoring

• Brief History of Refactoring

• Examples of refactoring steps

• How refactorings are performed

• When to refactor (code smells)

• Role of unit tests in refactoring

• Resources

24

How Refactorings are Performed

Either manually or automatically.

When done manually, it is always done in small steps (called refactorings).

Larger refactorings are sequences of smaller ones

25

Manual Refactoring

Manual refactoring steps should always be small, because: They are safer this way, because the

steps are simpler It is easier to backtrack

Pay attention to the mechanics: Mechanics should stress safety

26

How Refactorings are Performed When automatic support is

available, it should be preferred, but ...

... only if the tool is really safe. Example: Rename Method

Does it check for another method with the same name?

Does it account for overloading? Does it account for overriding?

27

Overview

Characterisation of Refactoring Brief History of Refactoring Examples of refactoring steps How refactorings are performed When to refactor (code smells) Role of unit tests in refactoring Resources

28

When to Refactor

We should refactor when the code stinks.

“If it stinks, change it.”Grandma Beck,discussing child-rearing philosophy

29

Refactoring and code smells

Refactorings remove Bad Smells in the Code i.e., potential problems or flaws

Some will be strong, some will be subtler

Some smells are obvious, some aren’t Some smells mask other problems Some smells go away unexpectedly

when we fix something else

30

Refactoring and code smells

Examples of code smells: Duplicated Code, Large Class, Lazy

Class, Long Method, Long Parameter List, Primitive Obsession, Speculative Generality, Temporary Field, Inappropriate Intimacy, Data Class, Refused Bequest, Comments, ...

Frequent cause:the paradigm shift problem

31

Refactoring and code smells

Code smells motivate use of refactorings to remove them, e.g.

Duplicated Code → Extract Method, Extract Class,

Form Template Method, ...

Long Method → Extract Method,Replace Temp with Query,Introduce Parameter

Object,Decompose Conditional,...

32

Overview

Characterisation of Refactoring Brief History of Refactoring Examples of refactoring steps How refactorings are performed When to refactor (code smells) Role of unit tests in refactoring Resources

33

Unit Tests

Essential prerequisite for refactoring:Solid tests (i.e. good unit test coverage) Tests warn programmers of problems if

they unknowningly break other parts of the application

Tests give an immediate/quick analysis of the effects of a change

Therefore tests give Courage

34

Unit Tests

Essential characteristic of unit tests: They must be automatic

No need to see console outputs No need to specially prepare them to run

They should independent of each other They should run often They should make it easy to run often

(otherwise developers will stop running them) They must be fast

35

Unit Tests

A test is not an unit test if: It talks to a database It communicates across a network It touches the file system

Such tests are good, but not fast enough to run in a suite of thousands of tests

Ciclo RED-GREEN-REFACTOR

Escrever um teste

Compilar

Corrigir os erros do compilador

Correr os testes e ver

a barra vermelha

Escrever novo código

Correr os testes e ver

a barra verde

Refabricar o código

(e testar)

Fase REDEscrever um teste

Compilar

Corrigir os erros do compilador

Correr os testes e ver

a barra vermelha

Escrever novo código

Correr os testes e ver

a barra verde

Refabricar o código

(e testar)

Fase RED

Fase GREEN

Escrever um teste

Compilar

Corrigir os erros do compilador

Correr os testes e ver

a barra vermelha

Escrever novo código

Correr os testes e ver

a barra verde

Refabricar o código

(e testar)

Fase RED

Fase GREEN

Fase REFACTOR

Escrever um teste

Compilar

Corrigir os erros do compilador

Correr os testes e ver

a barra vermelha

Escrever novo código

Correr os testes e ver

a barra verde

Refabricar o código

(e testar)

40

Overview

Characterisation of Refactoring Brief History of Refactoring Examples of refactoring steps How refactorings are performed When to refactor (code smells) Role of unit tests in refactoring Resources

41

Resources – TDD & refactoring

Refactoring home pagewww.refactoring.com/

Refactoring mailing list at Yahoogroups.yahoo.com/group/refactoring/

42

test-driven development:A Practical GuideDave AstelsPrentice-Hall/Pearson Education, 2003ISBN 0-13-101649-0

___________________________Test-Driven Development:By Example Kent BeckAddison-Wesley, 2003ISBN 0-321-14653-0

Resources – TDD & refactoring

43

Refactoring:Improving the Design of Existing CodeMartin FowlerAddison-Wesley, 1999ISBN 0-201-48567-2

Resources – TDD & refactoring

44

Refactoring Workbook

William WakeAddison-Wesley, 2003ISBN 0-32-110929-5

Resources – TDD & refactoring

45

Refactoring to PatternsJoshua KerievskyAddison-Wesley, 2004ISBN 0-321-21335-1

Resources – TDD & refactoring

46

JUnit Recipes –Practical Methods for Programmer Testing J.B. Rainsberger

Manning 2005

ISBN 1932394230

Resources – TDD & refactoring

47

Working Effectively with Legacy CodeMichael FeathersAddison-Wesley, 2005ISBN 0-13-117705-2

Resources – TDD & refactoring

48

Agile Java - Crafting Code with Test-Driven Development Jeff Langr

Prentice Hall 2005

ISBN 0-13-148239-4

Resources – TDD & refactoring

49

Refactoring and its role inTest-Driven Development

Questions?

Miguel J. T. Pessoa Monteiro

Escola Superior de Tecnologiade Castelo Branco