Refactoring Methods: Kevin Murphy
Situation 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; }
Replace Constructor with Factory Method Create a factory method. Make its body a call to the current constructor. Replace all calls to the constructor with calls to the factory method. Declare the constructor private.
Replace Constructor with Factory Method static Employee create(int type) { return new Employee(type); } Employee eng = Employee.create(Employee.ENGINEER); class Employee... private Employee (int type) { _type = type; }
Benefits Easier to use and follow in a program Can build multiple different subclasses out of the same method
Situation 2: class Order... Customer getCustomer() { return _customer; } void setCustomer (Customer arg) { if (_customer != null) _customer.friendOrders().remove(this); _customer = arg; if (_customer != null) _customer.friendOrders().add(this); } private Customer _customer; class Customer... void addOrder(Order arg) { arg.setCustomer(this); } private Set _orders = new HashSet(); Set friendOrders() { /** should only be used by Order */ return _orders; }
Replace Subclass with Fields Use Replace Constructor with Factory Method (304) on the subclasses. Declare final fields for each constant method on the superclass. Declare a protected superclass constructor to initialize the fields. Add or modify subclass constructors to call the new superclass constructor. Implement each constant method in the superclass to return the field and remove the method from the subclasses.
Replace Subclass with Fields class Person... static Person createMale(){ return new Male(); } static Person createFemale() { return new Female(); } class Person... private final boolean _isMale; private fi class Person... protected Person (boolean isMale, char code) { _isMale = isMale; _code = code;nal char _code; class Male... Male() { super (true, 'M'); } class Female... Female() { super (false, 'F'); }
Benefits Numerous classes can be reduced into one class Subclasses that only have constant functions are superfluous
Situation 3: class Order... Customer getCustomer() { return _customer; } void setCustomer (Customer arg) { if (_customer != null) _customer.friendOrders().remove(this); _customer = arg; if (_customer != null) _customer.friendOrders().add(this); } private Customer _customer; class Customer... void addOrder(Order arg) { arg.setCustomer(this); } private Set _orders = new HashSet(); Set friendOrders() { /** should only be used by Order */ return _orders; }
Bidirectional Association to Unidirectional Determine if the removal of the field in class 2 pointing at class 1 is possible Replace any calls to class 2 with calls to the field in class 1
Bidirectional Association to Unidirectional class Order... double getDiscountedPrice(Customer customer) { return getGrossPrice() * (1 - customer.getDiscount()); } class Customer... double getPriceFor(Order order) { Assert.isTrue(_orders.contains(order)); return order.getDiscountedPrice(this); }
Benefits Removes unnecessary connections Can save large amounts of data
Questions?