1 / 49

Refactoring and its role in Test-Driven Development

Refactoring and its role in Test-Driven Development. Miguel J. T. Pessoa Monteiro Escola Superior de Tecnologia de Castelo Branco. Overview. Characterisation of Refactoring Brief History of Refactoring Examples of refactoring steps How refactorings are performed

lana-kane
Download Presentation

Refactoring and its role in Test-Driven Development

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Refactoringand its role inTest-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. Intentionality is Important 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); }

  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 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. Rename Method The name of a method does not reveal its purpose. Change the name of the method.

  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. Pull Up Method You have methods with identical results on subclasses. Move them to the superclass.

  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 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 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 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 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. Opposite to Extract Method 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; }

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

  36. Ciclo RED-GREEN-REFACTOR Escrever um teste Refabricar o código(e testar) Compilar Corrigir os erros do compilador Correr os testes e vera barra verde Correr os testes e vera barra vermelha Escrever novo código

  37. Fase RED Escrever um teste Refabricar o código(e testar) Compilar Corrigir os erros do compilador Correr os testes e vera barra verde Correr os testes e vera barra vermelha Escrever novo código

  38. Fase RED Escrever um teste Refabricar o código(e testar) Compilar Corrigir os erros do compilador Correr os testes e vera barra verde Correr os testes e vera barra vermelha Escrever novo código Fase GREEN

  39. Fase RED Fase REFACTOR Escrever um teste Refabricar o código(e testar) Compilar Corrigir os erros do compilador Correr os testes e vera barra verde Correr os testes e vera barra vermelha Escrever novo código Fase GREEN

  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. Resources – TDD & refactoring 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

  43. Resources – TDD & refactoring Refactoring:Improving the Design of Existing Code Martin Fowler Addison-Wesley, 1999 ISBN 0-201-48567-2

  44. Resources – TDD & refactoring Refactoring Workbook William Wake Addison-Wesley, 2003 ISBN 0-32-110929-5

  45. Resources – TDD & refactoring Refactoring to Patterns Joshua Kerievsky Addison-Wesley, 2004 ISBN 0-321-21335-1

  46. Resources – TDD & refactoring JUnit Recipes –Practical Methods for ProgrammerTesting J.B. Rainsberger Manning 2005 ISBN 1932394230

  47. Resources – TDD & refactoring Working Effectively with Legacy Code Michael Feathers Addison-Wesley, 2005 ISBN 0-13-117705-2

  48. Resources – TDD & refactoring Agile Java - Crafting Code with Test-Driven Development Jeff Langr Prentice Hall 2005 ISBN 0-13-148239-4

  49. Refactoring and its role inTest-Driven Development Questions? Miguel J. T. Pessoa Monteiro Escola Superior de Tecnologiade Castelo Branco

More Related