Download presentation
Presentation is loading. Please wait.
Published byEstella Manning Modified over 8 years ago
1
REFACTORING CHANGE VALUE TO REFERENCE SUBSTITUTE ALGORITHM REPLACE CONDITIONAL WITH POLYMORHPISM
2
SUBSTITUTE ALGORITHM - MOTIVATION What’s Wrong? Hard to read Tedious to Modify Lengthy String foundPerson(String[] people){ for (int i = 0; i < people.length; i++) { if (people[i].equals ("Don")){ return "Don"; } if (people[i].equals ("John")){ return "John"; } if (people[i].equals ("Kent")){ return "Kent"; } } return ""; }
3
SUBSTITUTE ALGORITHM - EXAMPLE String foundPerson(String[] people){ List candidates = Arrays.asList(new String[] {"Don", "John", "Kent"}); for (int i=0; i<people.length; i++) if (candidates.contains(people[i])) return people[i]; return ""; } String foundPerson(String[] people){ for (int i = 0; i < people.length; i++) { if (people[i].equals ("Don")){ return "Don"; } if (people[i].equals ("John")){ return "John"; } if (people[i].equals ("Kent")){ return "Kent"; } } return ""; } Benefits: Shorter Easier to Read Add people by changing list No need to change control
4
CHANGE VALUE TO REFERENCE - MOTIVATION class Customer { public Customer (String name) { _name = name; } public String getName() { return _name; } private final String _name; } class Order... public Order (String customerName) { _customer = new Customer(customerName); } public void setCustomer(String customerName) { _customer = new Customer(customerName); } public String getCustomerName() { return _customer.getName(); } private Customer _customer; private static int numberOfOrdersFor(Collection orders, String customer) { int result = 0; Iterator iter = orders.iterator(); while (iter.hasNext()) { Order each = (Order) iter.next(); if (each.getCustomerName().equals(customer)) result++; } return result; } Classes Problems Each new order creates a new customer object Each customer can have many orders A lot of wasteful storage Client Code Example
5
CHANGE VALUE TO REFERENCE - EXAMPLE Load customers from DB in advance private static Dictionary _instances = new Hashtable(); class Customer... private Customer (String name) { _name = name; } static void loadCustomers() { new Customer ("Lemon Car Hire").store(); new Customer ("Associated Coffee Machines").store(); new Customer ("Bilston Gasworks").store(); } private void store() { _instances.put(this.getName(), this); } public static Customer getNamed (String name) { return (Customer) _instances.get(name); } Use a hash table to store/retrieve customers Private constructor to disallow new customer creation Factory method to handle customer creation SHOULD be from DB explicit code for example Store existing customers in hashtable Return the instance (reference) of customer with “name”
6
CHANGE VALUE TO REFERENCE - BENEFIT Customer class can reference existing customers Many orders can reference the same customer If a customer has a data change, the orders will not have to get new data or create new data. The referenced object changes for the orders class Order { public Order (String customer) { _customer = Customer.getNamed(customer); }
7
REPLACE CONDITIONAL WITH POLYMORPHISM - MOTIVATION Avoid writing an explicit conditional when you have objects whose behavior varies depending on their types. If you want to add a new Employee Type subclass you have to find and update all the conditionals Avoid high coupling between Employee Type and sub classes
8
class EmployeeType... int payAmount(Employee emp) { switch (getTypeCode()) { case ENGINEER: return emp.getMonthlySalary(); case SALESMAN: return emp.getMonthlySalary() + emp.getCommission(); case MANAGER: return emp.getMonthlySalary() + emp.getBonus(); default: throw new RuntimeException("Incorrect Employee"); } } REPLACE CONDITIONAL WITH POLYMORPHISM - EXAMPLE Different calculation for each paycheck High Coupling Let subclasses override payAmount class EmployeeType... abstract int payAmount(Employee emp); We Want:
9
REPLACE CONDITIONAL WITH POLYMORPHISM - EXAMPLE class EmployeeType... abstract int payAmount(Employee emp); We Want: class Employee... int payAmount() { return _type.payAmount(this); } class Engineer... int payAmount(Employee emp) { return emp.getMonthlySalary(); } class EmployeeType... int payAmount(Employee emp) { switch (getTypeCode()) { case ENGINEER: throw new RuntimeException ("Should be being overridden"); case SALESMAN: return emp.getMonthlySalary() + emp.getCommission(); case MANAGER: return emp.getMonthlySalary() + emp.getBonus(); default: throw new RuntimeException("Incorrect Employee"); } } ADDMODIFY
10
REPLACE CONDITIONAL WITH POLYMORPHISM - EXAMPLE class EmployeeType... abstract int payAmount(Employee emp); We Want: class Manager... int payAmount(Employee emp) { return emp.getMonthlySalary() + emp.getBonus(); } class EmployeeType... int payAmount(Employee emp) { switch (getTypeCode()) { case ENGINEER: throw new RuntimeException ("Should be being overridden"); case SALESMAN: throw new RuntimeException ("Should be being overridden"); case MANAGER: throw new RuntimeException ("Should be being overridden"); default: throw new RuntimeException("Incorrect Employee"); } } ADDMODIFY class Salesman... int payAmount(Employee emp) { return emp.getMonthlySalary() + emp.getCommission(); }
11
REPLACE CONDITIONAL WITH POLYMORPHISM - BENEFIT class EmployeeType... int payAmount(Employee emp) { switch (getTypeCode()) { case ENGINEER: throw new RuntimeException ("Should be being overridden"); case SALESMAN: throw new RuntimeException ("Should be being overridden"); case MANAGER: throw new RuntimeException ("Should be being overridden"); default: throw new RuntimeException("Incorrect Employee"); } } class EmployeeType... abstract int payAmount(Employee emp); No need to modify control structure Higher cohesion, lower coupling Reduces dependencies Easier to update / add new employee types BENEFIT
12
QUESTIONS?
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.