1 / 70

Section 3

Section 3. Payroll Case Study. The Payroll System – Initial Requirement. pay employees. correct amount (minus deductions). Employee Database. Payroll System. on time. method specified. Payroll Initial Spec. Pay Type:

aldona
Télécharger la présentation

Section 3

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Section 3 Payroll Case Study

  2. The Payroll System – Initial Requirement pay employees correct amount (minus deductions) Employee Database Payroll System on time method specified

  3. Payroll Initial Spec • Pay Type: • Hourly. Some employees work by the hour. Paid hourly rate. Submit time cards. Paid overtime @ 1.5 times rate. Paid every Friday. • Salary. Some employees salaried. Paid last working day of month. • Commission. Some employees also paid commission based on sales. Submit sales amounts. Paid every Friday. • Commission rate, salary, hourly rate are part of employee record. • Pay Method. • Employees can choose for paychecks to be mailed, held for pickup, or directly deposited to bank account. • Deductions. • Some employees belong to the union. Employee record has field for weekly dues rate. Must be deducted from pay. Union may assess service charges from time to time. These are submitted by union on weekly basis and must be deducted from appropriate employee’s next pay amount. • Other requirements. • Payroll application will run once each working day and pay the appropriate employees on that day. The system will be told to what date the employees are to be paid, so it will calculate payments from the last time the employee was paid up to the specified date.

  4. Chapter 18 Payroll Case Study

  5. How to begin? Obviously a database is involved. Should we generate a database schema and some queries? • Common – but this generates an application for which the database is the central concern. • Databases are implementation details! • Considering the database should be deferred as long as possible. • Abstraction: the amplification of the essential and the elimination of the irrelevant. The database is irrelevant at this stage; it is merely a technique used for storing and accessing data, nothing more.

  6. Analysis by Use Cases • Start by considering the behavior of the system. • Use case: similar to a story, but elaborated with more detail • Stories for this iteration: • Add a new employee • Delete an employee • Post a time card • Post a sales receipt • Post a union service charge • Change employee details (e.g., hourly rate, dues rate) • Run the payroll for today

  7. Use Case 1: Add New Employee A new employee is added by the receipt of an AddEmp transaction. This transaction contains the employee’s name, address, and assigned employee number. The transaction has 3 forms: AddEmp <EmpId> “<name>” “<address>” H <hourly-rate> AddEmp <EmpId> “<name>” “<address>” S <monthly-salary> AddEmp <EmpId> “<name>” “<address>” C <monthly-salary> <comm-rate> The employee record is created with fields assigned appropriately. Alternative 1: An error in the transaction structure. If the transaction structure is inappropriate, it is printed out in an error message and no action is taken.

  8. AddEmployee Transaction - Name - EmployeeId - Address Thinking about the design… • Use case 1 hints at an abstraction: We’ll look at the COMMAND pattern for this abstract base class… AddHourly Employee Transaction AddSalaried Employee Transaction AddCommissioned Employee Transaction SRP adhered to: each responsibility in its own class Don’t get sucked into the database yet!!

  9. OK to think about objects… Employee Hourly Employee Salaried Employee Commissioned Employee Possible Employee class hierarchy

  10. Use Case 2: Delete an Employee Employees are deleted when a DelEmp transaction is received. The form of this transaction is as follows: DelEmp <EmpId> When this transaction is received, the appropriate employee record is deleted. Alternative 1: Invalid or unknown EmpID If the <EmpID> field is not structured correctly, or it does not refer to a valid employee record, then the transaction is printed with an error message and no other action is taken. No design insights from this use case, so let’s move on…

  11. Use Case 3: Post Time Card On receiving a TimeCard transaction, the system will create a time-card record and associate it with the appropriate employee record. TimeCard <EmpId> <date> <hours> Alternative 1: The selected employee is not hourly The system will print an appropriate error message and take no further action Alternative 2: An error in the transaction structure The system will print an appropriate error message and take no further action

  12. Design insights… • Some transactions apply only to certain kinds of employees – strengthen case for different classes. • Indicates association between time cards and hourly employees. Hourly Employee 0..* TimeCard remember aggregation? Could also be composition, if TimeCard objects are destroyed when Employee is destroyed

  13. Use Case 4: Posting a Sales Receipt Upon receiving the SalesReceipt transaction, the system will create a new sales-receipt record and associate it with the appropriate commissioned employee. SalesReceipt <EmpId> <date> <amount> Alternative 1: The selected employee is not commissioned. The system will print an appropriate error message and take no further action. Alternative 2: An error in the transaction structure. The system will print an appropriate error message and take no further action.

  14. Design insights… • This is very similar to use case 3. It implies the following structure: Commissioned Employee 0..* Sales Receipt

  15. Use Case 5: Post Union Service Charge Upon receiving this transaction, the system will create a service-charge record and associate it with the appropriate union member. ServiceCharge <memberID> <amount> Alternative 1: Poorly formed transaction If the transaction is not well formed or if the <memberID> does not refer to an existing union member, then the transaction is printed with an appropriate error message.

  16. Design Insights… • Union members are not accessed through employee IDs. The union maintains its own numbering scheme. The system must be able to associate union members and employees. Could be done various ways, so postpone decision until later. Just show association for now. Example of how this differs from waterfall… 0..* UnionMember ServiceCharge

  17. Use Case 6: Change Employee Details Upon receiving this transaction the system will alter one of the details of the appropriate employee record. Several possible variations: ChgEmp <EmpID> Name <name> ChgEmp <EmpID> Address <address> ChgEmp <EmpID> Hourly <hourlyRate> // Change to hourly ChgEmp <EmpID> Salaried <salary> // Change to salary ChgEmp <EmpID> Commissioned <salary> <rate> ChgEmp <EmpID> Hold ChgEmp <EmpID> Direct <bank> <account> ChgEmp <EmpID> Mail <address> ChgEmp <EmpID> Member <memberID> Dues <rate> ChgEmp <EmpID> NoMember Alternative 1: An error in the transaction structure. If the transaction structure is inappropriate, or <EmpID> does not refer to a real employee, or <memberID> already refers to a member, then print a suitable error and take no further action

  18. Design insights… • Use case has shown all aspects of employee that are changeable. • Note that employees can change from hourly to salaried and vice versa. Initial class design may not be appropriate. Use STRATEGY pattern instead (see class diagram next slide) • Use the NULL OBJECT pattern for union membership.

  19. Salaried Classification - Salary DirectMethod - Bank - Account UnionAffiliation - Dues MailMethod - Address Hourly Classification - HourlyRate Updated class design <<interface>> Payment Method Employee <<interface>> Affiliation Payment Classification* NoAffiliation** HoldMethod 0..* ServiceCharge Commissioned Classification - CommissionRate - Salary 0..* 0..* *strategy class ** NULL object pattern TimeCard SalesReceipt

  20. Use Case 7: Run Payroll for Today Upon receiving the Payday transaction, the system finds all those employees that should be paid on the specified date. The system then determines how much they are owed and pays them according to their selected payment method. Payday <date>

  21. Finding Abstractions • Must hunt for abstractions, because often not stated or even alluded to by application requirements. • Example: • Some employees work by the hour • Some employees are paid a flat salary • Some employees are paid a commission • Generalization: All employees are paid, but they are paid by different schemes. • Abstraction: All employees are paid. Lead to PaymentClassification.

  22. Another abstraction • Scheduling the payroll: • They are paid every Friday • They are paid on last working day of month • They are paid every other Friday • Generality: All employees are paid according to some schedule. • Abstraction: schedule. • Use cases link schedule to payment classification. BUT, it seems possible that this could change (e.g., employees in different departments might be paid on different days). Also, if linked then a change in payment classification would require testing the schedule as well. • Schedule abstraction not included in original design

  23. Chapter 13 COMMAND and ACTIVE OBJECT

  24. COMMAND: simple + elegant public interface Command { public void do(); } <<interface>> Command + do() Elevates the role of a function to the level of a class. Blasphemy! But interesting designs can unfold…

  25. Simple Commands do() <<interface>> Command + do() do() RelayOn Command MotorOn Command ClutchOn Command init ClutchOnCommand MotorOnCommand RelayOff Command MotorOff Command ClutchOff Command Embedded real-time software for a photocopier. Pass Command() objects around system and call do() without knowing which type of Command they represent. (next slide…)

  26. Copier example, continued Sensor Command Example: sensor needs to engage clutch at point in paper path. Bind appropriate ClutchOnCommand to object. Sensor detects event, calls do(). Complexity of determining which relays to connect to which sensors is now handled by an initialization function.

  27. Transactions: a type of do() • Maintain database of employees. Number of operations that users can apply (add, delete, modify). • Command object collects unvalidated data, implements validation methods, executes transactions. <<interface>> Transaction + validate() + execute() Employee - name - address <<interface>> PayClassification + CalculatePay() AddEmployee Transaction - name - address + validate() + execute() <<interface>> Pay Classification + CalculatePay() Salaried Classification - monthlyPay Hourly Classification - hourlyRate Commissioned Classification - basePay - commissionRate 0..* 0..* SalesReceipt - date - amount TimeCard - date - amount

  28. Command Benefits • Physical and Temporal Decoupling • Decouple code that procures data from user (probably a dialog in some GUI) from code that validates and from business objects. If coupled, validation code couldn’t be used other places. Code that manipulates database should also be separate. • Temporal decoupling. Transaction data can be collected and processed later. For example, maybe changes to database should only occur in the evening. • Undo • Easy to add an undo() method to the COMMAND pattern. Can reverse the effects of a do().

  29. ACTIVE OBJECT • Old technique for implementing multiple threads of control. • Not covered – threads covered in OS and PL

  30. Chapter 14 TEMPLATE METHOD & STRATEGY Inheritance vs. Delegation

  31. Inheritance • Brave new world in early 90s • Could program by difference – find class that did something almost useful to us, create subclass and change only what didn’t work in new domain • BUT, easy to overuse inheritance • New advice: “Favor object composition over class inheritance” • Need to carefully consider, use inheritance, composition and delegation appropriately

  32. TEMPLATE METHOD - inheritance Common main-loop structure: Initialize(); while (!done()) // main loop { Idle(); // do something useful } Cleanup(); Use the pattern to create abstract base classes that can work on various types of objects.

  33. Example: Bubble Sorter • First, we have a sort that knows how to work with integers: public class BubbleSorter { static int operations = 0; public static int sort(int [] array) { operations = 0; if (array.length <= 1) return operations; for (int nextToLast = array.length-2; nextToLast >= 0; nextToLast--) for (int index = 0; index <= nextToLast; index++) compareAndSwap(array, index); return operations; } private static void swap (int[] array, int index) { int temp = array[index]; array[index] = array[index+1]; array[index+1] = temp; } private static void compareAndSwap (int[] array, int index) { if (array[index]> array[index+1]) swap(array, index); operations++; } }

  34. Bubble Sorter, continued • Can create abstract class instead: public abstract class BubbleSorter { private int operations = 0; protected int length = 0; protected int doSort() { operations = 0; if (length <= 1) return operations; for (int nextToLast = length-2; nextToLast >= 0; nextToLast--) for (int index = 0; index <= nextToLast; index++) { if (outOfOrder(index)) swap(index); operations++; } return operations; } protected abstract void swap(int index); protected abstract boolean outOfOrder (int index); } BubbleSorter {abstract} # outOfOrder # swap DoubleBubble Sorter IntBubble Sorter

  35. Bubble Sorter, continued • Implement methods for Int and Double: public class DoubleBubbleSorter extends BubbleSorter { private double[] array = null; public int sort(double [] theArray) { array = theArray; length = array.length; return doSort(); } protected void swap(int index) { double temp = array[index]; array[index] = array[index+1]; array[index+1] = temp; } protected boolean outOfOrder (int idx) { return (array[idx]> array[idx+1]); } } public class IntBubbleSorter extends BubbleSorter { private int[] array = null; public int sort(int [] theArray) { array = theArray; length = array.length; return doSort(); } protected void swap(int index) { int temp = array[index]; array[index] = array[index+1]; array[index+1] = temp; } protected boolean outOfOrder (int idx) { return (array[idx]> array[idx+1]); } }

  36. Application Runner + run STRATEGY pattern • Another way to solve the problem of inverting the dependencies • Instead of putting generic application algorithm in an abstract class, place it in a concrete class named ApplicationRunner • Abstract methods that must be called are defined in the Application interface • ftocStrategy is derived from this interface. An object of this class can be passed to ApplicationRunner ftoc = fahrenheit to celcius <<interface>> Application + init + idle + cleanup + done: boolean concrete class ftocStrategy concrete class

  37. Strategy code public class ApplicationRunner { private Application itsApplication = null; public ApplicationRunner(Application app) { itsApplication = app; } public void run() { itsApplication.init(); while (!itsApplication.done()) itsApplication.idle(); itsApplication.cleanup(); } } can pass in ftocStrategy, etc. public interface Application { public void init(); public void idle(); public void cleanup(); public boolean done(); } calls methods from interface

  38. Strategy code, continued import java.io.*; public class ftocStrategy implements Application { private InputStreamReader isr; private BufferedReader br; private boolean isDone = false; public static void main(String[] args) throws Exception { (new ApplicationRunner(new ftocStrategy())).run(); } public void init() { isr = new InputStreamReader(System.in); br = new BufferedReader(isr); } // More code in textbook

  39. Strategy pros and cons • Strategy involves more classes • Delegation pointer in ApplicationRunner incurs some overhead BUT • Easy to reuse ApplicationRunner by passing in different implementations of Application

  40. Another example – sorting again public class BubbleSorter { private int operations = 0; private int length = 0; private SortHandle itsSortHandle = null; public BubbleSorter(SortHandle handle) { itsSortHandle = handle; } public int sort(Object array) { itsSortHandle.setArray(array); length = itsSortHandle.length(); operations = 0; if (length <= 1) return operations; for (int nextToLast = length-2; nextToLast >= 0; nextToLast--) for (int index = 0; index <= nextToLast; index++) { if (itsSortHandle.outOfOrder(index)) itsSortHandle.swap(index); operations++; } return operations; }} public interface SortHandle { public void swap(int index); public boolean outOfOrder(int index); public int length(); public void setArray(Object array); }

  41. Sorting continued public class IntSortHandle implements SortHandle { private int[] array = null; public void swap(int index) { int temp = array[index]; array[index] = array[index+1]; array[index+1] = temp; } public void setArray(Object array) { this.array = (int[])array; } public int length() { return array.length; } public boolean outOfOrder(int index) { return (array[index] > array[index+1]); } } • Notice: • IntSortHandle knows nothing of BubbleSorter • IntSortHandle could therefore be used with other sorts – e.g., QuickBubbleSorter that stops when the array is in order (code in text) • Strategy allows the details to be reused independently of the high-level algorithm! More comparison sorts covered in CSCI406

  42. Chapter 15 FAÇADE and MEDIATOR

  43. Policy patterns • Both Façade and Mediator impose some kind of policy on another group of objects • Façade imposes policy from above • Mediator imposes policy from below • Façade is visible and constraining • Mediator is invisible and enabling

  44. Facade • Used to provide a simple, specific interface for a group of objects that has a complex, general interface Product-specific sql interface; complex but shields users from knowing sql details public class DB { private static Connection con; public static void init() throws Exception {…} public static void store(ProductData pd) throws Exception {…} // Products private static PreparedStatement buildProductInsertionStatement ProductData pd) throws SQLException public static ProductData getProductData(String sku) throws Exception private static PreparedStatement buildProductQueryStatement(String sku) private static ProductData extractProductDataFromResultSet(ResultSet rs) public static void store(ItemData id) throws Exception {…} // Items private static PreparedStatement buildItemInsersionStatement(ItemData id) public static ItemData[] getItemsForOrder(int orderId) throws Exception private static PreparedStatement buildItemsForOrderQueryStatement (int orderId) throws SQLException private static ItemData[] extractItemDataFromResultSet(ResultSet rs) public static OrderData newOrder(String customerId) throws Exception private static int getMaxOrderId() throws SQLException // Orders public static OrderData getOrderData(int orderId) throws SQLException private static void executeStatement(PreparedStatement s) public static void close() throws Exception {…} public static void clear() throws Exception {…} }

  45. DB Facade DB + store(ProductData) + getProductData(sku) + deleteProductData(sku) … Application ProductData java.sql Connection Statement DriverManager Prepared Statement ResultSet SQLException All database calls must go through DB. Direct calls to java.sql violate convention. Policy is visible – application sees interface it provides. Valid operations are all provided. Simplifies – application programmers don’t all need to learn sql interface, just use DB.

  46. Mediator • Imposes policy in hidden, constrained way. QuickEntryMediator selects the first entry in a list that matches the current prefix in a JTextField. State JList JTextField CO ALABAMA ALASKA ARIZONA ARKANSAS CALIFORNIA COLORADO CONNECTICUT DELAWARE <<anonymous>> Document Listener QuickEnty Mediator Hidden: Users of JList and JTextField have no idea that this Mediator exists.

  47. Mediator QuickEntry Example State List of states public class QuickEntryMediator { public QuickEntryMediator(JTextField t, JList l) { itsTextField = t; itsList = l; itsTextField.getDocument().addDocumentListener( new DocumentListener() { public void changedUpdate(DocumentEvent e) { textFieldChanged(); } public void insertUpdate(DocumentEvent e) { textFieldChanged(); } public void removeUpdate(DocumentEvent e) { textFieldChanged(); } } // new DocumentListener ); // addDocumentListener } // QuickEntryMediator() responds to JTextField events, shown on next slide

  48. Mediator QuickEntry continued private void textFieldChanged() { String prefix = itsTextField.getText(); if (prefix.length() == 0) { // clear selection if user clears field itsList.clearSelection(); return; } ListModel m = itsList.getModel(); // finds first item that matches boolean found = false; // text typed so far for (int i = 0; found == false && i < m.getSize(); i++) { Object o = m.getElementAt(i); String s = o.toString(); if (s.startsWith(prefix)) { itsList.setSelectedValue(o, true); found = true; // found is true if any items in list match prefix } } if (!found) { // clear if nothing matches text entry itsList.clearSelection(); } } // textFieldChanged private JTextField itsTextField; private JList itsList; } // class QuickEntryMediator

  49. Chapter 16 SINGLETON and MONOSTATE

  50. Sometimes you only need one… • Normally there is a one-to-many relationship between classes and objects • Some classes should only have one instance • factories • managers (e.g., print, other resources) • root of application • If more than one, logic errors may occur • May be able to just create one when application starts and be done with it • Sometimes it is important to enforce singularity • Two patterns to do that: singleton & monostate application root

More Related