refactoring - a disciplined approach to rework for better design

36
Refactoring - A disciplined approach to rework for better design.

Upload: merryl-williamson

Post on 01-Jan-2016

222 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Refactoring - A disciplined approach to rework for better design

Refactoring

- A disciplined approach to rework for better design.

Page 2: Refactoring - A disciplined approach to rework for better design

Objectives

•What is refactoring?•History•Why should I refactor? •When should I refactor?•How to refactor?

Page 3: Refactoring - A disciplined approach to rework for better design

Definition•Refactoring is a disciplined technique for

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

• It makes the software easier to understand and cheaper to modify.

Page 4: Refactoring - A disciplined approach to rework for better design

Continued..•Example: compute gravitational potential energy

▫PEgrav = mass * g * height

double potentialEnergy(double mass, double height) { return mass * height * 9.81; }

static final double GRAVITATIONAL_CONSTANT = 9.81;

double potentialEnergy(double mass, double height) { return mass * height * GRAVITATIONAL_CONSTANT; }

Magic number

Page 5: Refactoring - A disciplined approach to rework for better design

Properties of Refactoring

•One step at a time

•Preserve correctness

•Frequent testing

Page 6: Refactoring - A disciplined approach to rework for better design

Where did refactoring come from ?

For a long time it was a piece of programmer lore, done withvarying degrees of discipline by experienced developers, butnot passed on in a coherent way.

• Kent Beck and Ward Cunningham were two of the first people to recognize the importance of refactoring▫ worked with Smalltalk from the 80's onward.

• Ralph Johnson's work with refactoring and frameworks has also been an important contribution.

• Martin Fowler’s book Refactoring: Improving the Design of Existing Code is the classic reference.

Page 7: Refactoring - A disciplined approach to rework for better design

Why refactor?• Improves the design of software.

▫Without refactoring, the design of the program will decay

•Makes software easier to understand.▫A good design is easy to understand

•Helps you find bugs.▫The clarification process helps find bugs

•Helps you program faster.▫Poor design slow you down

Page 8: Refactoring - A disciplined approach to rework for better design

When to Refactor? •As you develop

▫Example: change a variable name to something more meaningful.

•Before adding functions.▫Sometimes the existing design does not allow you to easily

add the feature.•When you need to fix a bug

▫The bug exists because the code was not clear enough for you to see the bug in the first place.

•When you do a code review▫Code reviews help spread knowledge through the

development team.▫Works best with small review groups

Page 9: Refactoring - A disciplined approach to rework for better design

Steps to refactoring

• Identifying bad smells of code▫a “bad smell” = a warning sign in the code▫e.g., time consuming code

•Designing solid tests ▫for the section of code under analysis.

•Refactoring the code ▫based on the type of the smell

•Applying tests.

Page 10: Refactoring - A disciplined approach to rework for better design

Bad Smells in Code•Duplicated Code•Long Method•Large Class•Long Parameter List•Divergent Change•Shotgun Surgery•Feature Envy•Data Clumps•Primitive Obsession•Switch Statements

• Parallel Interface Hierarchies• Lazy Class• Speculative Generality• Temporary Field• Message Chains • Middle Man• Inappropriate Intimacy• Incomplete Library Class• Data Class• Refused Bequest

Page 11: Refactoring - A disciplined approach to rework for better design

Bad smells in code•Smells within classes

▫Duplicated code▫Long method▫Large class▫…

•Smells between classes▫Primitive obsession ▫ Inappropriate intimacy▫Middle man▫…

Page 12: Refactoring - A disciplined approach to rework for better design

Duplicated Code – (1)

•“The #1 bad smell” ▫If you see the same code structure in more than one

place, you can be sure that your program will be better if you find a way to unify them.

▫What if duplicates changes

•Refactoring solutions▫Pull up a field▫Form a template method▫Substitute algorithm

Page 13: Refactoring - A disciplined approach to rework for better design

Duplicated Code – (2)•Pull up a field

▫Two subclasses have the same field.▫Move the field to the superclass.

Salesman Engineer

Employee

name name

Page 14: Refactoring - A disciplined approach to rework for better design

Duplicated Code – (3)•Form a template method

▫You have two methods in subclasses that perform similar steps in the same order, yet the steps are different.

▫Get the steps into methods with the same signature, so that the original methods become the same. Then you can pull them up.

Page 15: Refactoring - A disciplined approach to rework for better design

Duplicated Code – (4)•Form a template method

PersonalCustomer

CorporateCustomer

Customer

getBillableAmt() getBillableAmt()

double base=unit*ratedouble tax=base*Site.TAX_RATE;return base+tax

double base=unit*rate*0.5double tax=base*Site.TAX_RATE*0.2;return base+tax

getBaseAmt()getTaxAmt()

getBaseAmt()getTaxAmt()

return getBaseAmt()+getTaxAmt()

getBaseAmt()getTaxAmt()

Page 16: Refactoring - A disciplined approach to rework for better design

Duplicated Code – (5)• Substitute algorithm

▫ Replace the body of the method with the new algorithm.

duplications

Page 17: Refactoring - A disciplined approach to rework for better design

Long Method – (1)

•The longer the method the harder it is to see what it’s doing. ▫Poorly thought out abstractions and boundaries

•Refactoring solutions▫Extract method▫Replace temp with query▫ Introduce parameter object▫Preserve whole object

Page 18: Refactoring - A disciplined approach to rework for better design

Long Method – (2)

•Extract method▫ break up into smaller

private methods within the class

• Example

private void m1(){Statement 1;..Statement 9;}

private void m2(){Statement 10;..Statement 19;}

private void m3(){Statement 20;..Statement 30;}

public void methodA(){

}

public void methodA(){

Statement 1;Statement 2;..Statement 30;} m1();

m2();

m3();

Page 19: Refactoring - A disciplined approach to rework for better design

Long Method – (3)• Replace temp with query

▫You are using a temporary variable to hold the result of an expression.

▫Extract the expression into a method.

if (basePrice() > 1000) { return basePrice() * 0.95;} else { return basePrice() * 0.98; }

Temp variable

expression

double basePrice=basePrice();if (basePrice > 1000) { return basePrice * 0.95;} else { return basePrice * 0.98; }

Page 20: Refactoring - A disciplined approach to rework for better design

Long Method – (4)• Introduce parameter object

▫A group of parameters that naturally go together.▫Replace them with an object.

amountInvoicedIn ( )amountReceivedIn ( )amountOverdueIn ( )

Customerstart: Dateend: Date

DateRangeDateRange

Start: Date, end: DateStart: Date, end: DateStart: Date, end: Date

DateRangeDateRange

Page 21: Refactoring - A disciplined approach to rework for better design

Long Method – (5)•Preserve whole object

▫You are getting several values from an object and passing these values as parameters in a method call.

▫Send the whole object instead.

Page 22: Refactoring - A disciplined approach to rework for better design

Large Class – (1)

•A class that is trying to do too much ▫Can usually be identified by looking at how many

instance variables it has. ▫When a class has too many instance variables,

duplicated code cannot be far behind. •Refactoring solution

▫Extract class▫Extract subclass

Page 23: Refactoring - A disciplined approach to rework for better design

PhoneNumber

Large Class – (2)•Extract class

▫Have one class doing work that should be done by two.▫Need create a new class and move the relevant fields

and methods from the old class into the new class.

Customer

nameareaCodenumber

String: getPhoneNumber()

PhoneNumber: getPhoneNumber()

Page 24: Refactoring - A disciplined approach to rework for better design

LaborItem

Large Class – (3)• Extract subclass

▫A class has features that are used only in some instances.

▫Create a subclass for that subset of features.

JobItem

getTotalPrice()getUnitPrice()getEmployee()

Do all the JobItem objects need have getEmployee

function?

getUnitPrice()

Page 25: Refactoring - A disciplined approach to rework for better design

Primitive Obsession – (1)•Over use primitive to represent data

▫All properties of a class are primitive types int, String, boolean, double, etc.

▫Primitive difficult to represent data money (which combines quantity and currency) a date range object

• Refactorings▫Replace data value with object ▫Replace type code with class

Page 26: Refactoring - A disciplined approach to rework for better design

Primitive Obsession – (2)•Replace data value with objects

▫You have a data item that needs additional data or behavior.

▫Turn the data item into an object.

Order

customer: String

Customer

id: Stringlast Name:: StringmiddleName: StringfirstName: Stringphone: PhoneNumber

Page 27: Refactoring - A disciplined approach to rework for better design

Primitive Obsession – (3)•Replace type code with class

▫A class has a numeric type code that does not affect its behavior.

▫Replace the number with a new class.

Person

O: intA: intB:intAB:int

BloodType

O: BloodTypeA: BloodTypeB: BloodTypeAB: BloodType

bloodType:int

public class Person{ …… int bloodType =BloodType.O; …….}

public class BloodType{ public static final int O 1; public static final int A 2; public static final int B 3; public static final int AB 4;}

Page 28: Refactoring - A disciplined approach to rework for better design

Inappropriate Intimacy – (1)•Two classes are overly entertwined

▫Sharing of secrets between classes▫Leads to data coupling

•Refactorings▫Hide delegate▫Replace inheritance with delegation

Page 29: Refactoring - A disciplined approach to rework for better design

What is that?

Inappropriate Intimacy – (2)•Hide delegate

▫A client is calling a delegate class of an object.▫Create methods on the server to hide the delegate.

Client

Server

Delegate

taskA() taskA()

public void method(){ delegate.taskA();}

Page 30: Refactoring - A disciplined approach to rework for better design

Inappropriate Intimacy – (3)

ClientClass

Employee

Department

getDepartment() getManager()

public class Department{ private Employee manager; …… public Department (Employee manager){ this.manager=manager; } public string getManager(){ return manager; } …..}

manager=john.

Object need to know less about other parts of the

system

public getManager(){ return department.getManager();}

getManager()

getDepartment().

getManager();

Page 31: Refactoring - A disciplined approach to rework for better design

Inappropriate Intimacy – (3)• Replace inheritance with delegation

▫ A subclass uses only part of a superclasses interface or does not want to inherit data.

▫ Create a field for the superclass, adjust methods to delegate to the superclass, and remove the subclassing.

Page 32: Refactoring - A disciplined approach to rework for better design

Middle ManInline Method• A method's body is just as clear as its name • Refactoring solution

▫ 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;

}

Page 33: Refactoring - A disciplined approach to rework for better design

Why might you still not refactor your programs?•You might not understand how to refactor.

• If the benefits are long-term, why exert the effort now? In the long term, you might not be with the project to reap the benefits!

•Refactoring code is an overhead activity; you're paid to write new features.

•Refactoring might break the existing program.

Page 34: Refactoring - A disciplined approach to rework for better design

Summary•Refactoring is a disciplined approach to rework

for better design.•Refactor when code smells.•Take advantage of IDE (Eclipse/IntelliJ/ Java

Studio).•Check online resources for updated refactoring.•Know refactoring before your interview.

Page 35: Refactoring - A disciplined approach to rework for better design

References

•http://wiki.java.net/bin/view/People/SmellsToRefactorings

•https://netfiles.uiuc.edu/dig/RefactoringInfo/

•http://www.refactoring.com/

Page 36: Refactoring - A disciplined approach to rework for better design

Questions?