Lectures 17 and 18 A Refactoring Micro-Example FOR0383 Software Quality Assurance 5/16/20151Dr Andy Brooks Refactoring is really easy using this tool.

Slides:



Advertisements
Similar presentations
12-Dec-14 Refactoring IV. Previously discussed bad smells Duplicated code — and other forms of redundancy Long method — use short methods that delegate.
Advertisements

Test-Driven Development and Refactoring CPSC 315 – Programming Studio.
About Me – Frank Xu Education ▫ North Dakota State University  Ph.D. in Software Engineering ▫ Towson University  MS in Computer Science ▫ Southeast.
Written by: Dr. JJ Shepherd
You want me to do what??? Refactoring legacy applications aka : fixing someone else’s “bad” code Niel Zeeman Team Foundation Consulting
Refactoring Overview  What is refactoring?  What are four good reasons to refactor?  When should you refactor?  What is a bad smell (relative to refactoring.
Software Construction and Evolution - CSSE 375 Bad Smells in Code Shawn Bohner & Steve Chenoweth.
Inheritance. Extending Classes It’s possible to create a class by using another as a starting point  i.e. Start with the original class then add methods,
OOP in Java Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler.
XP and Refactoring David Talby. Development Methodologies The Software Crisis – 84% of software projects are not on time – 31% of software projects never.
REFACTORING Improving the Design of Existing Code Atakan Şimşek e
Building Java Programs Inner classes, generics, abstract classes reading: 9.6, 15.4,
13-Jul-15 Refactoring II. Books Design Patterns is the classic book by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides Basically a catalog.
Principles of Computer Programming (using Java) Review Haidong Xue Summer 2011, at GSU.
REFACTORING Lecture 4. Definition Refactoring is a process of changing the internal structure of the program, not affecting its external behavior and.
1 v1.6 08/02/2006 Overview of Eclipse Lectures 1.Overview 2.Installing and Running 3.Building and Running Java Classes 4.Refactoring 5.Debugging 6.Testing.
Refactoring Cristescu Marilena. Definitions Loose Usage: Reorganize a program(or something) As a noun: a change made to the internal structure of some.
Software Refactoring Part I: Introduction Bartosz Walter Advanced Object-Oriented Design Lecture 5.
Method Overriding Remember inheritance: when a child class inherits methods, variables, etc from a parent class. Example: public class Dictionary extends.
Refactoring. Mathematics: Factor ● fac·tor – One of two or more quantities that divides a given quantity without a remainder, e.g., 2 and 3 are factors.
Refactoring - A disciplined approach to rework for better design.
Refactoring Improving the structure of existing code Refactoring1.
CSC 1051 – Data Structures and Algorithms I Dr. Mary-Angela Papalaskari Department of Computing Sciences Villanova University Course website:
Small changes to code to improve it. Refactoring Defined A change made to the internal structure of software to make it easier to understand and cheaper.
SWE 316: Software Design and Architecture Objectives Lecture # 20 Improving the existing design: Refactoring SWE 316: Software Design and Architecture.
Best Practices. Contents Bad Practices Good Practices.
Refactoring1 Improving the structure of existing code.
The effectiveness of refactoring based on a compatibility testing taxonomy and a dependency graph Steve Counsell and Robert Hierons, Brunel University,
Refactoring Deciding what to make a superclass or interface is difficult. Some of these refactorings are helpful. Some research items include Inheritance.
1 CSC/ECE 517 Fall 2010 Lec. 3 Overview of Eclipse Lectures Lecture 2 “Lecture 0” Lecture 3 1.Overview 2.Installing and Running 3.Building and Running.
Incremental Design Why incremental design? Goal of incremental design Tools for incremental design  UML diagrams  Design principles  Design patterns.
Software Engineering CS3003 Lecture 4 Code bad smells and refactoring.
Refactoring. Refactoring Overview  What is refactoring?  What are four good reasons to refactor?  When should you refactor?  What is a bad smell (relative.
Chapter 21 Test-Driven Development 1CS6359 Fall 2011 John Cole.
Refactoring 2. Admin Blackboard Quiz Acknowledgements Material in this presentation was drawn from Martin Fowler, Refactoring: Improving the Design of.
REFACTORINGREFACTORING. Realities Code evolves substantially during development Requirements changes 1%-4% per month on a project Current methodologies.
Chapter 6 Introduction to Defining Classes. Objectives: Design and implement a simple class from user requirements. Organize a program in terms of a view.
Refactoring II Dealing with Polymorphism. Switch in Rental Switches on Movie! class Rental … public double getCharge() { double result = 0; switch (getMovie().getPriceCode()){
Module 3. Smells Between Classes Course: Refactoring.
Writing Maintainable code Dr. Susan McKeever DT228/3 GUI Programming.
1 Software Maintenance and Evolution CSSE 575: Session 3, Part 3 Dealing with Generalization Steve Chenoweth Office Phone: (812) Cell: (937)
An Advanced Code Pattern: Inner Classes CSE301 University of Sunderland Harry R. Erwin, PhD Half Lecture.
SEG 4110 – Advanced Software Design and Reengineering Topic T Introduction to Refactoring.
Refactoring. Mathematics: Factor ● fac·tor – One of two or more quantities that divides a given quantity without a remainder, e.g., 2 and 3 are factors.
CSSE 375 Organizing Data – Part 2 Shawn and Steve Continue the same quiz!
Refactoring1 Improving the structure of existing code.
Pertemuan 12 Refactoring Mata kuliah: T0144 – Advanced Topics in Software Engineering Tahun: 2010.
Refactoring. 2 Process of changing a software system in such a way that it does not alter the external behavior of the code, yet improves its internal.
CSSE 375 Organizing Data – Part 1 Shawn and Steve Q1.
Software Construction and Evolution - CSSE 375 Dealing with Generalization Steve and Shawn Left – In the 1990 movie “The Freshman,” Matthew Broderick,
Refactoring. DCS – SWC 2 Refactoring ”A change made to the internal structure of software to make it easier to understand and cheaper to modify without.
Module 9. Dealing with Generalization Course: Refactoring.
9.1 CLASS (STATIC) VARIABLES AND METHODS Defining classes is only one aspect of object-oriented programming. The real power of object-oriented programming.
CSC 1051 – Data Structures and Algorithms I Dr. Mary-Angela Papalaskari Department of Computing Sciences Villanova University Course website:
Geoff Holmes and Bernhard Pfahringer COMP206-08S General Programming 2.
University of British Columbia CPSC 111, Intro to Computation Jan-Apr 2006 Tamara Munzner Class Design II Lecture 7, Thu Jan
Refactoring (1). Software Evolution Cope with change Feature bloat Design decay Code duplications “Pattern time is refactoring time” Make future changes.
Principles and examples
Catalog of Refactoring
Catalog of Refactoring
Module Road Map Refactoring Why Refactoring? Examples
A Very Common Series of Techniques
Refactoring II 21-Sep-18.
Overview of Eclipse Lectures
Code Smells 1.
Improving the structure of existing code
Refactoring II 5-Feb-19.
Refactoring.
Presentation transcript:

Lectures 17 and 18 A Refactoring Micro-Example FOR0383 Software Quality Assurance 5/16/20151Dr Andy Brooks Refactoring is really easy using this tool.

16/05/2015Dr Andy Brooks2 Case Study Dæmisaga Reference A Refactoring Micro-Example, David Parsons,

16/05/2015Dr Andy Brooks3 What is refactoring? There is a dedicated website: “Refactoring is the process of improving the design of existing code without changing its observable behaviour.” “It is an ongoing process of continual cleanup.” Dave Parsons

16/05/2015Dr Andy Brooks4 Replace smelly code Signs of decay include: –Duplicated code –Switch statements –Long methods –Large classes –Data classes (only getters and setters in the API) –Long parameter lists –Use of primitives rather than objects –Temporary variables and fields When you write smelly code you are hacking...

16/05/2015Dr Andy Brooks5 Test the changes Every refactoring change should be tested. Recompile and test after every change. “If we want to refactor, the essential precondition is having solid tests.” Martin Fowler

16/05/2015Dr Andy Brooks6 Fowler´s ‘Rule of Three’ The first time you write something you just do it. The second time, you wince at the duplication. The third time, you refactor. ‘Two hats rule’ Do not try to develop code at the same time as you refactor code. Refactor while you wear your refactoring hat: do not develop. R D

16/05/2015Dr Andy Brooks7 The micro example A method of some dice game class that throws a couple of dice and returns a result. ‘dice’ is an array of ‘Die’. public int getScore() { int result; result = (int)(Math.random() * 6) + 1; dice[0].setFaceValue(result); result = (int)(Math.random() * 6) + 1; dice[1].setFaceValue(result); int score = dice[0].getFaceValue() + dice[1].getFaceValue(); return score; } 0<=x<1 1<=x<7 (int) truncates fraction

16/05/2015Dr Andy Brooks8 Refactoring 1 – Self Encapsulate Field Use accessor methods, do not directly access an object´s fields within its methods. public int getScore() { int result; result = (int)(Math.random() * 6) + 1; getDice(0).setFaceValue(result); result = (int)(Math.random() * 6) + 1; getDice(1).setFaceValue(result); int score =getDice(0).getFaceValue() +getDice(1).getFaceValue(); return score; } The underlying representation of a die can be changed.

16/05/2015Dr Andy Brooks9 Refactoring 2 – Extract Method Split up a longer method into smaller methods. public int getScore() { int result; result = rollDie(); getDice(0).setFaceValue(result); result = rollDie(); getDice(1).setFaceValue(result); int score = getDice(0).getFaceValue() + getDice(1).getFaceValue(); return score; } public int rollDie() { return (int)(Math.random() * 6) + 1; }

16/05/2015Dr Andy Brooks10 Refactoring 3 – Rename class/method/field Change names to be more meaningful. public int throwDice () { int result; result = rollDie(); getDice(0).setFaceValue(result); result = rollDie(); getDice(1).setFaceValue(result); int score = getDice(0).getFaceValue() + getDice(1).getFaceValue(); return score; } public int rollDie() { return (int)(Math.random() * 6) + 1; }

16/05/2015Dr Andy Brooks11 Refactoring 4 – Replace Temp with Query Use a query method instead of a temporary variable. public int throwDice() {int result; result = rollDie(); getDice(0).setFaceValue(result); result = rollDie(); getDice(1).setFaceValue(result); return getDiceValue();} public int rollDie() {return (int)(Math.random() * 6) + 1;} int getDiceValue() {return getDice(0).getFaceValue() + getDice(1).getFaceValue();}

16/05/2015Dr Andy Brooks12 Refactoring 5 – Move Method Dice objects are data objects. It would be better to move the rollDie() method to the Dice class and have this method set the state of the object. The rollDie() method can also be renamed to roll(). public void roll() { setFaceValue((int)(Math.random() * 6) + 1); }

16/05/2015Dr Andy Brooks13 Refactoring 5 – Move Method public int throwDice() { getDice(0).roll(); getDice(1).roll(); return getDiceValue(); } int getDiceValue() { return getDice(0).getFaceValue() + getDice(1).getFaceValue(); } The code is beginning to look much cleaner.

16/05/2015Dr Andy Brooks14 Refactor 6 – Replace conditional with polymorphism Switch statements that depend on the type of an object should be replaced with class hierarchies and polymorphic methods. Suppose the Die class had code to model two kinds of dice: NORMAL or LOADED. static final int NORMAL = 1; static final int LOADED = 2; private int type;

16/05/2015Dr Andy Brooks15 Refactor 6 – Replace conditional with polymorphism public void roll() { switch(getType()) { case NORMAL: setFaceValue((int)(Math.random() * 6) + 1); break; case LOADED: // random is a static java.util.Random object – easier // to fix a range of integers (2 – 6) than Math.random setFaceValue(random.nextInt(5) + 2); break; default: setFaceValue(1); } The roll() method now has a switch. inclusive of 0 exclusive of 5

16/05/2015Dr Andy Brooks16 Refactor 6 – Replace conditional with polymorphism Die NormalLoaded //Normal Die implementation public void roll() { setFaceValue((int)(Math.random() * 6) + 1); } //Loaded Die implementation public void roll() { setFaceValue(random.nextInt(5) + 2); } abstract superclass

16/05/2015Dr Andy Brooks17 Refactor 7 – Replace Magic Number with Symbolic Constant public static final int MAX_RANDOM = 6; public static final int MIN_DICE_VALUE = 2; public void roll() { setFaceValue(random.nextInt(MAX_RANDOM - 1) + MIN_DICE_VALUE); } 6 rather than 5 because we want to express the maximum value of a die.

16/05/2015Dr Andy Brooks18 Replace indexed access with iteration? The real question is: do we need indexed access if we just have two die objects? The answer is no. We will ‘never’ need to be able to use a different number of dice. The use of an array or collection provides too much functionality. We just need two named die objects: public int throwDice() { getDice(0).roll(); getDice(1).roll(); return getDiceValue(); } indexed access getFirstDie().roll(); getSecondDie().roll();

16/05/2015Dr Andy Brooks19 Replace polymorphism with parameterised algorithm Do we really need to use inheritance and have a polymorphic roll() method? No. We could make use of a parameterised method. If you have two algorithms that do something similar, consider if they can be combined into a single algorithm in a parameterised method. int getRandomInt(int min, int max);

16/05/2015Dr Andy Brooks20 Knowing that we will only ever have two die and recognising that a parameterised method can be used to model a normal and loaded die... completely changes the look of the code...

16/05/2015Dr Andy Brooks21 Reflections Were the refactorings carried out in the right order? Can refactorings be prioritised? Should refactoring first consider core architectural issues? Should we start with the simplest refactorings?

16/05/2015Dr Andy Brooks22 Reflections Refactorings are often reversible. ‘Replace Inheritance with Delegation’ and ‘Replace Delegation with Inheritance’. We may do a refactoring only to undo it. A tool providing a direct link between software metric scores and suggested refactorings would be very useful.

16/05/2015Dr Andy Brooks23 Some refactoring examples explained with the help of UML.

16/05/2015Dr Andy Brooks24 Pull Up Field Eliminating duplicate fields can help reduce defects and allows methods that use the fields to be moved to the superclass.

16/05/2015Dr Andy Brooks25 Push Down Field Push a field down if it is not needed in the superclass.

16/05/2015Dr Andy Brooks26 Pull Up Method Eliminating duplicate methods can help reduce defects.

16/05/2015Dr Andy Brooks27 Push Down Method Methods should be pushed down if the they are not used by all the subclasses.

16/05/2015Dr Andy Brooks28 Replace inheritance with delegation class Sub extends Super {...} Suppose an object of Sub never uses the methods ying() and yang(). Class Sub should then not inherit from class Super.

16/05/2015Dr Andy Brooks29 Replace inheritance with delegation class Sub { Super s = new Super(); int foo() { return s.foo(); } // delegation void bar() { s.bar(); } // delegation int baz() {...} // new method }

16/05/2015Dr Andy Brooks30 Replace delegation with inheritance class Sub { Super s = new Super(); int foo() { return s.foo(); } // delegation void bar() { s.bar(); } // delegation char ying() {return s.ying();} // delegation char yang() {return s.yang();} // delegation int baz() {...} // new method }

16/05/2015Dr Andy Brooks31 Replace delegation with inheritance Suppose an object of Sub uses all of the methods foo(), bar(), ying() and yang(). Class Sub should then inherit from class Super. class Sub extends Super {...}

32 Hide Delegate Hide a delegate class (Department) by creating a method on the server (Person). manager = andy.getDepartment().getManager(); manager = andy.getManager();

33 Remove Middle Man The server class (Person) is delegating too much, so have the client call the delegate class (Department) directly. manager = andy.getManager(); manager = andy.getDepartment().getManager();

16/05/2015Dr Andy Brooks34 Hide Delegate and Remove Middle Man: Which refactoring is appropriate depends on the number of delegating methods involved (such as getManager()). If there are a lot of delegating methods then the client should access the delegated class directly.

16/05/2015Dr Andy Brooks35 Hide Method If a method is not used by any other class make the visibility private.

16/05/2015Dr Andy Brooks36 Do no forget the Two Hats Rule. Refactor code in the context of a testing framework. Each change has to be tested. Do not forget many refactorings come in pairs. A refactoring may be reversed at a later date. The part played by data members can influence a refactoring decision. There are many more recognised refactorings.