30
Today’s Agenda More refactoring patterns Software Testing and Maintenance 1

Today’s Agenda More refactoring patterns Software Testing and Maintenance 1

Embed Size (px)

Citation preview

Page 1: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Today’s Agenda

More refactoring patterns

Software Testing and Maintenance 1

Page 2: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Introduce Null Object (1)

class Site … Customer getCustomer () { return _customer; }

class Customer … public String getName () { … } public BillingPlan getPlan () { … } public PaymentHistory getHistory () { … }

Customer customer = site.getCustomer ();BillingPlan plan;if (customer == null) plan = BillingPlan.basic ();else plan = customer.getPlan ();…String customerName;if (customer == null) customerName = “occupant”;else customerName = customer.getName (); …

Software Testing and Maintenance 2

Page 3: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Introduce Null Object (2)

class NullCustomer extends Customer { public boolean isNull () { return true; } public String getName () { return “occupant”; } public BillingPlan getPlan () { return BillingPlan.basic (); }

class Customer … static Customer newNull () { return new NullCustomer (); }

class Site … Customer getCustomer () { return (_customer == null) ? Customer.newNull () : _customer;

}

Software Testing and Maintenance 3

Page 4: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Introduce Null Object (3)

Customer customer = site.getCustomer ();BillingPlan plan;plan = customer.getPlan ();…

String customerName;customerName = customer.getName (); …

Software Testing and Maintenance 4

Page 5: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Data Value with Object (1)

class Order public Order (String customer) {

_customer = customer; } public String getCustomer () { return _customer; } public void setCustomer (String customer) { _customer = customer; } private String _customer;

Software Testing and Maintenance 5

What if we need to add address or credit rating into a customer?

Page 6: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Data Value with Object (2)

class Customer { public Customer (String name) { _name = name; } public String getName () { return _name; } private final String _name;}class Order … public order (String customer) { _customer = new Customer (customer); } public String getCustomer () { return _customer.getName (); } private Customer _customer; public void setCustomer (String customer) { _customer = new Customer (customer); }

Software Testing and Maintenance 6

Page 7: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Change Value to Reference

class Order { public order (String customer) { _customer = Customer.create (customer); }}class Customer { private Customer (String name) { _name = name; } static void loadCustomer () { new Customer (“Bilston Gasworks”).store(); new Customer (“Jeff Bridge”).store(); … } private void store () { _instances.put(this.getName(), this); } public static Customer create (String name) { return (Customer) _instances.get(name); } private static Dictionary _instances = new Hashtable ();}

Software Testing and Maintenance 7

Page 8: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Magic Number with Sym. Constantdouble potentialEnergy (double mass, double height) { return mass * 9.81 * height;}

Software Testing and Maintenance 8

double potentialEnergy (double mass, double height) { return mass * GRAVITATIONAL_CONSTANT * height;}Static final double GRAVITATIONAL_CONSTANT = 9.81;

Page 9: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Separate Query from Modifier

int getTotalOutstandingAndSetReadyForSummaries () { readyForSummaries = true; return outstanding; }

Software Testing and Maintenance 9

int getTotalOutstanding () { return outstanding; }

void setReadyForSummaries () { readyForSummaries = true;}

Page 10: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Parameterize Method

class Employee { void tenPercentRaise () { salary *= 1.1; } void fivePercentRaise () { salary *= 1.05; }}

Software Testing and Maintenance 10

class Employee { void raise (double factor) { salary *= (1 + factor); }}

Page 11: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Parameter with Explicit Methods

void setValue (String name, int value) { if (name.equals(“height”)) { _height = value; return; } if (name.equals(“width”)) { _width = value; return; }}

Software Testing and Maintenance 11

void setHeight (int arg) { _height = arg;}Void setWidth (int arg) { _width = arg;}

Page 12: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Parameter with Method (1)

public double getPrice () { int basePrice = _quantity * _itemPrice; int discountLevel; if (_quantity > 100) discountLevel = 2; else discountLevel = 1; double finalPrice = discountedPrice (basePrice, discountLevel); return finalPrice;}

private double discountedPrice (int basePrice, int discountLevel) { if (discountLevel == 2) return basePrice * 0.1; else return basePrice * 0.05;}

Software Testing and Maintenance 12

Page 13: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Parameter with Method (2)

public double getPrice () { if (getDiscountLevel() == 2) return getBasePrice() * 0.1; else return getBasePrice() * 0.05;}

private double getBasePrice () { return _quantity * _itemPrice;}

private int getDiscountLevel () { if(_quantity > 100) return 2; else return 1;}

Software Testing and Maintenance 13

Page 14: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Constructor with Factory Method (1)class Employee { private int _type; static final int ENGINEER = 0; static final int SALESMAN =

1; static final int MANAGER = 2;

Employee (int type) { _type = type; }}

Software Testing and Maintenance 14

class Employee { static Employee create (int type)

{ switch (type) { case ENGINEER: return new Engineer (); case SALESMAN: return new Salesman (); case MANAGER: return new Manager (); default: // throw an exception }}

Page 15: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Constructor with Factory Method (2)

Software Testing and Maintenance 15

static Employee create (String name) { try { return (Employee) Class.forName (name).newInstance(); } catch (Exception ex) { throw new IllegalArgumentException(“Unable to instantiate ” +

name); }}

Employee.create(“Engineer”);Employee.create(“Manager”);…

Page 16: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Encapsulate Downcast

Object lastReading () { return readings.lastElement ();}

Reding lastReading = (Reading) site.lastReading ();

Software Testing and Maintenance 16

Reading lastReading () { return (Reading) readings.lastElement ();}

Reding lastReading = site.lastElement();

Page 17: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Error Code with Exception (1)

class Account … int withdraw (int amount) { if (amount > _balance) return -1; else { _balance -= amount; return 0; } } private int _balance;

Software Testing and Maintenance 17

Page 18: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Error Code with Exception (2)

class Account … void withdraw (int amount) { if (amount > _balance) throw new IllegalArgumentException (“Amount too large”); _balance -= amount; } private int _balance;

Software Testing and Maintenance 18

Page 19: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Error Code with Exception (3)

class Account … void withdraw (int amount) throws BalanceException { if (amount > _balance) throw new BalanceException (); _balance -= amount; } private int _balance;

Software Testing and Maintenance 19

Page 20: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Pull Up Constructor Body

class Manager extends Employee … public Manager (String name, String id, int grade) { _name = name; _id = id; _grade = grade; }

Software Testing and Maintenance 20

class Employee … public Employee (String name, string id) { _name = name; _id = id; }

class Manager extends Employee … public Manager (String name, String id, int grade) { super (name, id); _grade = grade; }

Page 21: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Extract Subclass (1)

class JobItem … public JobItem (int unitPrice, int quantity, boolean isLabor, Employee employee) { _unitPrice = unitPrice; _quantity = quantity; … } public int getTotalPrice () { return getUnitPrice () * quantity; } public int getUnitPrice () { return (_isLabor) ? _employee.getRate() : _unitPrice; } ….

class Employee… public Employee (int rate) { _rate = rate; } public int getRate () { return _rate; } private _rate;

Software Testing and Maintenance 21

Page 22: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Extract Subclass (2)

class JobItem … public JobItem (int unitPrice, int quantity, boolean isLabor) { _unitPrice = unitPrice; _quantity = quantity; _isLabor = isLabor; } public int getUnitPrice () { return _unitPrice; } ….

class LaborItem extends JobItem … public LaborItem (int quantity, Employee employee) { super (0, quantity, true); _employee = employee; } public int getUnitPrice () { return _employee.getRate (); }

Software Testing and Maintenance 22

Page 23: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Extract Subclass (3)

Modify calls to the constructor of the job item where a labor item is constructed

Software Testing and Maintenance 23

JobItem j = new JobItem (0, 5, true, kent);

JobItem j = new LaborItem (5, kent);

Page 24: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Form Template Method (1)

public String statement () { Enumeration rentals = _rentals.elements (); String result = “Rental Record for ” + getName () + “\n”; while (rentals.hasMoreElements ()) { Rental each = (Rental) rentals.nextElement (); // show figures for this rental result += “\t” + each.getMovie.getTitle() + “\t” + String.valueOf(each.getCharge()) + “\n”; } // add footer lines result += “Amount owed is“ + String.valueOf(getTotalCharge()) + “\n”; result += “You earned “ + String.valueOf(getTotalFrequentRenterPoints()) + “ frequent renter points”; return result;}

Software Testing and Maintenance 24

Page 25: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Software Testing and Maintenance 25

Form Template Method (2)

public String htmlStatement () { Enumeration rentals = _rentals.elements (); String result = “<H1>Rental Record for <EM>” + getName () + “</EM></H1><P>\n”; while (rentals.hasMoreElements ()) { Rental each = (Rental) rentals.nextElement (); // show figures for this rental result += each.getMovie.getTitle() + “: ” + String.valueOf(each.getCharge()) + “<BR>\n”; } // add footer lines result += “<P>You owe <EM> “ + String.valueOf(getTotalCharge()) + “</EM><P>\n”; result += “On this rental you earned “ + String.valueOf(getTotalFrequentRenterPoints()) + “ </EM>frequent renter points <P>”; return result;}

Page 26: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Form Template Method (3)

Software Testing and Maintenance 26

Customer Statement

Text Statement

HTMLStatement

Page 27: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Software Testing and Maintenance 27

Form Template Method (4)

class Statement … public String value (Customer customer) { Enumeration rentals = customer.getRentals (); String result = headerString(customer); while (rentals.hasMoreElements ()) { Rental each = (Rental) rentals.nextElement (); // show figures for this rental result += eachRentalString(each); } // add footer lines result += footerString(customer); return result; } abstract String headerString (Customer customer); abstract String eachRentalString (Rental rental); abstract String footerString (Customer customer);

Page 28: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Software Testing and Maintenance 28

Form Template Method (5)

class TextStatement … String headerString (Customer customer) { return “Rental Record for “ + customer.getName () + “\n”; }

String eachRentalString (Rental rental) { return “\t” + rental.getMovie().getTitle() + “\t” + String.valueOf(rental.getCharge() + “\n”; }

String footerString (Customer customer) { return “Amount owed is “ + String.valueOf(customer.getTotalCharge()) + “\n” + “You earned “ + String.valueOf(customer.getTotalFrequentRenterPoints()) + “ frequent renter points”; }

// similar for class HtmlStatement

Page 29: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Inheritance with Delegation (1)

class MyStack extends Vector { public void push (Object element) { insertElementAt (element, 0); } public Object pop () { Object result = firstElement (); removeElementAt (0); return result; }}

Software Testing and Maintenance 29

Page 30: Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1

Replace Inheritance with Delegation (2)

class MyStack { private Vector _vector = new Vector ();

public void push (Object element) { _vector.insertElementAt (element, 0); } public Object pop () { Object result = _vector.firstElement (); _vector.removeElementAt (0); return result; } public int size () { return _vector.size (); } public boolean isEmpty () { return _vector.isEmpty (); }}

Software Testing and Maintenance 30