Top Banner
Refactoring Thierry Sans with slides from Anya Tafliovich
26

Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Jun 17, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Refactoring

Thierry Sans

with slides from Anya Tafliovich

Page 2: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Composing Methods

Page 3: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Extract Method

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

void printDetails(double outstanding) { System.out.println("name: " + name); System.out.println("amount: " + outstanding); }

void printOwing() { printBanner();

//print details System.out.println("name: " + name); System.out.println("amount: " + getOutstanding()); }

Page 4: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Extract Variables

double price () {

final double basePrice = _quantity * _itemPrice;

final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05;

final double shipping = Math.min(basePrice * 0.1, 100.0);

return basePrice – discount + shipping;

}

double price () {

// price is base price – quantity discount + shipping

return _quantity * _itemPrice -

Math.max(0, _quantity – 500) * _itemPrice * 0.05 +

Math.min(_quantity * _itemPrice * 0.1, 100.0);

}

Page 5: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Organizing Data

Page 6: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Replace magic number with symbolic constant

static final double GRAVITY = 9.81;

double potentialEnergy(double mass, double height) {

return mass * GRAVITY * height;

}

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

Page 7: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Encapsulate field

private String _name; public String getName() { return _name; } public void setName(String name) { _name = name; }

Page 8: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Encapsulate collectionclass Student { private Set<Course> _courses; Set<Course> getCourses() { return _courses; } void setCourses(Set<Course> courses) { _courses = courses; } }

class Student { private Set<Course> _courses; Set<Course> getCourses() { return Collections.unmodifiableSet(_courses); } void setCourses(Set<Course> courses) { _courses = new HashSet<>(); for (Course c : courses) _courses.add(c); } }

Page 9: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Simplifying Conditional Expressions

Page 10: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Consolidate conditional expression

double disabilityAmount() {

if ( _seniority < 2 ) return 0;

if ( _monthsDisabled > 12 ) return 0;

if ( _isPartTime ) return 0;

// now compute disability amount (lots of code here)

}

double disabilityAmount() {

if ( _seniority < 2 || _monthsDisabled > 12 || _isPartTime) return 0;

// now compute disability amount (lots of code here)

}

Page 11: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Consolidate conditional expression + Extract method

double disabilityAmount() {

if ( isNotEligibleForDisability() ) return 0;

// now compute disability amount (lots of code here)

}

boolean isNotEligibleForDisability() {

return ( _seniority < 2 || _monthsDisabled > 12 || _isPartTime);

}

Page 12: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Consolidate duplicate conditional fragments

if ( isSpecialDeal() )

total = price * 0.95;

else

total = price + surcharge * 0.98;

send();

if ( isSpecialDeal() ) {

total = price * 0.95;

send();

} else {

total = price + surcharge * 0.98;

send();

}

Page 13: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Remove control flags

for (i=0, i<l.length, i++){ if (l[i+1] == 'key') break; }

boolean found false; i = 0; while (!found || i<l.length){ if (l[i+1] == 'key') found = true; }

Page 14: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Replace nested conditionals

double getPayAmt() { if ( _isSingle ) return singleAmount(); if ( _isSeparated ) return separatedAmount(); if ( _isRetired ) return retiredAmount(); return normalPayAmount(); }

double getPayAmt() { double result; if ( _isSingle ) result = singleAmount(); else { if ( _isSeparated ) result = separatedAmount(); else { if ( _isRetired ) result = retiredAmount(); else result = normalPayAmount(); } } return result; }

Page 15: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Replace nested conditionals + Extract method

double getAdjustedCapital() {

if ( _capital <= 0.0 || _intRate <= 0.0 || _duration <= 0.0 )

return 0.0;

return (_income / _duration) * ADJ_FACTOR;

}

double getAdjustedCapital() {

if ( noAdjustment() ) return 0.0;

return (_income / _duration) * ADJ_FACTOR;

}

boolean noAdjustment() {

return ( _capital <= 0.0 || _intRate <= 0.0 || _duration <= 0.0 );

}

Page 16: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Replace conditional with polymorphismdouble payAmount() {

switch ( _type ) {

case EmployeeType.ENGINEER:

return _monthlySalary;

case EmployeeType.SALESMAN:

return _monthlySalary + _commission;

case EmployeeType.MANAGER:

return _monthlySalary + _bonus;

default:

throw new RuntimeException(“Incorrect Employee”);

}

}

Page 17: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Introduce Null Object

Customer customer

if ( _customer == null )

plan = BillingPlan.basic();

else

plan = _customer.getPlan();

if ( _customer != null )

_customer.setName(n);

if ( _customer != null )

points = _customer.getPoints();

else

points = 0;

...

Page 18: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Simplifying Method Calls

Page 19: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Parametrize methodclass Employee {

void fivePercentRaise() {…}

void tenPercentRaise() {…}

}

class Employee {

void percentRaise(double p) {…}

void fivePercentRaise() { percentRaise(5); } // if still used

void tenPercentRaise() { percentRaise(10); } // if still used

}

Page 20: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Replace parameter with explicit methodsvoid setValue(String name, int value) {

if ( name.equals(“height”) ) {

_height = value;

return;

}

if ( name.equals(“width”) ) {

_width = value;

return;

}

}

void setHeight(int value) {

_height = value;

}

void setWidth(int value) {

_width = value;

}

Page 21: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Dealing with Generalization

Page 22: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Extract Superclass

Page 23: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Pull up method/field

Page 24: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Push down method/field

Page 25: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Replace inheritance with delegation

Page 26: Refactoring - Thierry SansExtract Variables double price {final double basePrice = _quantity * _itemPrice; final double discount = Math.max(0,_quantity–500)*_itemPrice*0.05; final

Replace delegation with inheritance