Download presentation
Presentation is loading. Please wait.
Published byCoral Cannon Modified over 9 years ago
1
Refactoring and its role in Test-Driven Development Miguel J. T. Pessoa Monteiro Escola Superior de Tecnologia de Castelo Branco
2
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
3 Refactoring Tenet of Refactoring Program source code is a mechanism of communication between humans, not between the programmer and the computer.
4
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
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
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
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
8 What is not Refactoring Adding new functionality is not refactoring Optimisation is not refactoring Changing code that does not compile is not refactoring (what would be the behaviour?)
9
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
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
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
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
13 Reverse Conditional You 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
14 Rename Method The name of a method does not reveal its purpose. Change the name of the method.
15
15 Move Method A 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
16 Pull Up Method You have methods with identical results on subclasses. Move them to the superclass.
17
17 Extract Method You 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 details System.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
18 Extract Method You 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 details System.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
19 Inline Method A 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
20 Inline Method A 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
21 Replace Conditional with Polymorphism You 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
22 Replace Conditional with Polymorphism You 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
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
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
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
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
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
28 When to Refactor We should refactor when the code stinks. “If it stinks, change it.” Grandma Beck, discussing child-rearing philosophy
29
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
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
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
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
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
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
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
36
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)
37
Fase RED 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)
38
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)
39
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
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
41 Resources – TDD & refactoring Refactoring home page www.refactoring.com/ Refactoring mailing list at Yahoo groups.yahoo.com/group/refactoring/
42
42 test-driven development: A Practical Guide Dave Astels Prentice-Hall/Pearson Education, 2003 ISBN 0-13-101649-0 ___________________________ Test-Driven Development: By Example Kent Beck Addison-Wesley, 2003 ISBN 0-321-14653-0 Resources – TDD & refactoring
43
43 Refactoring: Improving the Design of Existing Code Martin Fowler Addison-Wesley, 1999 ISBN 0-201-48567-2 Resources – TDD & refactoring
44
44 Refactoring Workbook William Wake Addison-Wesley, 2003 ISBN 0-32-110929-5 Resources – TDD & refactoring
45
45 Refactoring to Patterns Joshua Kerievsky Addison-Wesley, 2004 ISBN 0-321-21335-1 Resources – TDD & refactoring
46
46 JUnit Recipes – Practical Methods for Programmer Testing J.B. Rainsberger Manning 2005 ISBN 1932394230 Resources – TDD & refactoring
47
47 Working Effectively with Legacy Code Michael Feathers Addison-Wesley, 2005 ISBN 0-13-117705-2 Resources – TDD & refactoring
48
48 Agile Java - Crafting Code with Test-Driven Development Jeff Langr Prentice Hall 2005 ISBN 0-13-148239-4 Resources – TDD & refactoring
49
49 Refactoring and its role in Test-Driven Development Questions? Miguel J. T. Pessoa Monteiro Escola Superior de Tecnologia de Castelo Branco
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.