重構—改善既有程式的設計(chapter 8)part 1
Post on 15-Dec-2014
711 Views
Preview:
DESCRIPTION
TRANSCRIPT
Copyright 2009 Trend Micro Inc.
New Hires Orientation
Refactoring Ch8 (part 1)Mel Huang
Copyright 2009 Trend Micro Inc.
Outline
• 8.1 Self Encapsulate Field
• 8.2 Replace Data Value with Object
• 8.3 Change Value to Reference
• 8.4 Change Reference to Value
• 8.5 Replace Array with Object
• 8.6 Duplicate Observed Data
• 8.7 Change Unidirectional Association to Bidirectional
• 8.8 Change Bidirectional Association to Unidirectional
Classification 04/10/2023 2
Copyright 2009 Trend Micro Inc.
8.1 Self Encapsulate Field
Classification 04/10/2023 3
private int _low, _high;boolean includes (int arg) { return arg >= _low && arg <= _high;}
private int _low, _high;boolean includes(int arg) { return arg >= getLow() && arg <= getHigh();}int getLow() { return _low; }int getHigh() { return _high; }int setLow(int low) { _low = low; }int setHigh(int high) { _high = high; }
direct access: simple!
getter/setter: flexible!
Copyright 2009 Trend Micro Inc.
8.2 Replace Data Value with Object
Classification 04/10/2023 4
class Order { public Order (String customer) { _customer = customer; } private String _customer;}
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); } private Customer _customer;}
data value object: easier to complicate data
item(s)
Copyright 2009 Trend Micro Inc.
8.3 Change Value to Reference
Classification 04/10/2023 5
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); } private Customer _customer;}
class Customer { public static Customer create (String name) { return (Customer) _instances.get(name); } static void loadCustomers() { new Customer("Lemon Car Hire").store(); new Customer("Associated Coffee Machines").store(); ... } private void store() { _instances.put(this.getName(), this); } public String getNamed(String name) { return (Customer) _instances.get(name); } private final String _name; private static Dictionary _instances = new Hashtable();}
class Order { public Order (String customer) { _customer = Customer.create(customer); } private Customer _customer;}
Order Customer
Order Customer
…
Order
Order Customer
…
*
*
Copyright 2009 Trend Micro Inc.
8.4 Change Reference to Value
Classification 04/10/2023 6
class Currency { private String _code;
public String getCode() { return _code; } private Currency (String code) { _code = code; }}
class Currency { private String _code;
public String getCode() { return _code; } private Currency (String code) { _code = code; } public boolean equals(Object arg) { if (! (arg instanceof Currency)) return false; Currency other = (Currency) arg; return (_code.equals(other._code)); } public int hashCode() { return _code.hashCode(); }}
immutable?
Copyright 2009 Trend Micro Inc.
8.5 Replace Array with Object
Classification 04/10/2023 7
String[] row = new String[3];row[0] = "Liverpool";row[1] = "15";
Performance row = new Performance();row.setName("Liverpool");row.setWins("15");
array: hard to remember each column
object: easy to maintain
Copyright 2009 Trend Micro Inc.
8.6 Duplicate Observed Data
Classification 04/10/2023 8
public class IntervalWindow extends Frame { TextField _startField; TextField _endField; TextField _lengthField;
void StartField_FocusLost(FocusEvent event) { ... calculateLength(); } void EndtField_FocusLost(FocusEvent event) { ... calculateLength(); } void StartField_FocusLost(FocusEvent event) { ... calculateLength(); }
void calculateLength() { ... } void calculateEnd() { ... }}
public class IntervalWindow extends Frame implements Observer { private Interval _subject; TextField _startField; TextField _endField; TextField _lengthField;
public IntervalWindow() { _subject = new Interval(); _subject.addObserver(this); update(_subject, null); } public void update(Observable observed, Object arg) { _endField.setText(_subject.getEnd()); } String getEnd() { return _subject.getEnd(); } void setEnd (Srting arg) { _subject.setEnd(arg); } void StartField_FocusLost(FocusEvent event) { ... calculateLength(); } void EndtField_FocusLost(FocusEvent event) { ... calculateLength(); } void StartField_FocusLost(FocusEvent event) { ... calculateLength(); }}
class Interval extends Observable { void calculateLength() { ... } void calculateEnd() { ... }}
Copyright 2009 Trend Micro Inc.
8.7 Change Unidirectional Association to Bidirectional
Classification 04/10/2023 9
class Order { Customer getCustomer() { return _customer; } void setCustomer (Customer arg) { _customer = arg; } Customer _customer; // order->customer}
class Customer { private Set _orders = new HashSet();}
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); } Customer _customer; // order->customer}
class Customer { private Set _orders = new HashSet(); Set friendOrders() { return _orders } void addOrder(Order arg) { arg.setCustomer(this); }}
Order Customer*Order Customer*
Copyright 2009 Trend Micro Inc.
8.8 Change Bidirectional Association to Unidirectional
Classification 04/10/2023 10
Order Customer*Order Customer*
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); } double getDiscountedPrice() { return getGrossPrice() * (1 - _customer.getDiscount()); } Customer _customer; // order->customer}
class Customer { getPriceFor(Order order) { Assert.isTrue(_orders.contains(order)); return order.getDiscountedPrice(); }}
class Order { Customer getCustomer() { return _customer; } Customer setCustomer () { Iterator iter = Customer.getInstances().iterator(); while (iter.hasNext()) { Customer each = (Customer)iter.next(); if (each.containsOrder(this)) return each; } return null; } double getDiscountedPrice(Customer customer) { return getGrossPrice() * (1 - customer.getDiscount()); } Customer _customer; // order->customer}
class Customer { getPriceFor(Order order) { Assert.isTrue(_orders.contains(order)); return order.getDiscountedPrice(this); }}
Copyright 2009 Trend Micro Inc.
Thank You
Classification 04/10/2023 11
top related