Analysis by Use Cases


Instead of starting with the data of the system, let's start by considering the behavior of the system. After all, it is the system's behavior that we are being paid to create.

One way to capture and analyze the behavior of a system is to create use cases. As originally described by Jacobson, use cases are very similar to the notion of user stories in XP.[1] A use case is like a user story that has been elaborated with a little more detail. Such elaboration is appropriate once the user story has been selected for implementation in the current iteration.

[1] [Jacobson92]

When we perform use case analysis, we look to the user stories and acceptance tests to find out the kinds of stimuli that the users of this system provide. Then we try to figure out how the system responds to those stimuli. For example, here are the user stories that our customer has chosen for the next iteration:

  1. Add a new employee

  2. Delete an employee

  3. Post a time card

  4. Post a sales receipt

  5. Post a union service charge

  6. Change employee details (e.g., hourly rate, dues rate, etc.)

  7. Run the payroll for today

Let's convert each of these user stories into an elaborated use case. We don't need to go into too much detail: just enough to help us think through the design of the code that fulfills each story.

Adding Employees

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 three forms:

  1. AddEmp <EmpID> "<name>" "<address>" H <hrly-rate>

  2. AddEmp <EmpID> "<name>" "<address>" S <mtly-slry>

  3. AddEmp <EmpID> "<name>" "<address>" C <mtly-slry> <com-rate>

The employee record is created with its 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.


Use case 1 hints at an abstraction. The AddEmp transaction has three forms, all of which share the <EmpID>, <name>, and <address> fields. We can use the COMMAND pattern to create an AddEmployeeTransaction abstract base class with three derivatives: AddHourlyEmployeeTransaction, AddSalariedEmployeeTransaction, and AddCommissionedEmployeeTransaction (see Figure 26-1).

Figure 26-1. AddEmployeeTransaction class hierarchy


This structure conforms nicely to the Single-Responsibility Principle (SRP) by splitting each job into its own class. The alternative would be to put all these jobs into a single module. Although doing so might reduce the number of classes in the system and therefore make the system simpler, it would also concentrate all the transaction-processing code in one place, creating a large and potentially error-prone module.

Use case 1 specifically talks about an employee record, which implies some sort of database. Again. our predisposition to databases may tempt us into thinking about record layouts or the field structure in a relational database table, but we should resist these urges. What the use case is really asking us to do is create an employee. What is the object model of an employee? A better question might be: What do the three transactions create? In my view, they create three kinds of employee objects, mimicking the three kinds of AddEmp transactions. Figure 26-2 shows a possible structure.

Figure 26-2. Possible Employee class hierarchy


Deleting Employees

Use Case 2: Deleting 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 does not refer to a valid employee record, the transaction is printed with an error message, and no other action is taken.


Other than the obvious DeleteEmployeeTransaction class, I'm not getting any particular insight from use case 2. Let's move on.

Posting Time Cards

Use Case 3: Post a Time Card

On receipt of 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.


This use case points out that some transactions apply only to certain kinds of employees, strengthening the idea that each kind should be represented by different classes. In this case, there is also an association implied between time cards and hourly employees. Figure 26-3 shows a possible static model for this association.

Figure 26-3. Association between HourlyEmployee and TimeCard


Posting Sales Receipts

Use Case 4: Post a Sales Receipt

On receipt of the SalesReceipt TRansaction, the system will create a new salesreceipt record and associate it with the appropriate commissioned employee.

SalesReceipt <EmpID> <date> <amount>


Alternative 1: The selected employee 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.


This use case is very similar to use case 3 and implies the structure shown in Figure 26-4.

Figure 26-4. Commissioned employees and sales receipts


Posting a Union Service Charge

Use Case 5: Post a Union Service Charge

On receipt of 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, the transaction is printed with an appropriate error message.


This use case shows that union members are not accessed through employee IDs. The union maintains its own identification numbering scheme for union members. Thus, the system must be able to associate union members and employees. There are many ways to provide this kind of association, so to avoid being arbitrary, let's defer this decision until later. Perhaps constraints from other parts of the system will force our hand one way or another.

One thing is certain. There is a direct association between union members and their service charges. Figure 26-5 shows a possible static model for this association.

Figure 26-5. Union members and service charges


Changing Employee Details

Use Case 6: Changing Employee Details

Upon receipt of this transaction, the system will alter one of the details of the appropriate employee record. There are several possible variations to this transaction.

ChgEmp <EmpID> Name <name>

Change employee name

ChgEmp <EmpID> Address <address>

Change employee address

ChgEmp <EmpID> Hourly <hourlyRate>

Change to hourly

ChgEmp <EmpID> Salaried <salary>

Change to salaried

ChgEmp <EmpID> Commissioned <salary> <rate>

Change to commissioned

ChgEmp <EmpID> Hold

Hold paycheck

ChgEmp <EmpID> Direct <bank> <account>

Direct deposit

ChgEmp <EmpID> Mail <address>

Mail paycheck

ChgEmp <EmpID> Member <memberID> Dues <rate>

Put employee in union

ChgEmp <EmpID> NoMember

Cut employee from union


Alternative 1: Transaction errors

If the structure of the transaction is improper, <EmpID> does not refer to a real employee, or <memberID> already refers to a member, the system will print a suitable error and take no further action.


This use case is very revealing. It has told us all the employee aspects that must be changeable. The fact that we can change an employee from hourly to salaried means that the diagram in Figure 26-2 is certainly invalid. Instead, it would probably be more appropriate to use the STRATEGY pattern for calculating pay. The Employee class could hold a strategy class named PaymentClassification, as in Figure 26-6. This is an advantage because we can change the PaymentClassification object without changing any other part of the Employee object. When an hourly employee is changed to a salaried employee, the HourlyClassification of the corresponding Employee object is replaced with a SalariedClassification object.

Figure 26-6. Revised class diagram for Payroll: the core model


PaymentClassification objects come in three varieties. The HourlyClassification objects maintain the hourly rate and a list of TimeCard objects. The Salaried-Classification objects maintain the monthly salary figure. The Commissioned-Classification objects maintain a monthly salary, a commission rate, and a list of SalesReceipt objects.

The method of payment must also be changeable. Figure 26-6 implements this idea by using the STRATEGY pattern and deriving three kinds of PaymentMethod classes. If the Employee object contains a MailMethod object, the corresponding employee will have paychecks mailed to the address recorded in the MailMethod object. If the Employee object contains a DirectMethod object, the corresponding employee's pay will be directly deposited into the bank account recorded in the DirectMethod object. If the Employee contains a HoldMethod object, the corresponding employee's paychecks will be sent to the paymaster to be held for pickup.

Finally, Figure 26-6 applies the NULL OBJECT pattern to union membership. Each Employee object contains an Affiliation object, which has two forms. If the Employee contains a NoAffiliation object, the corresponding employee's pay is not adjusted by any organization other than the employer. However, if the Employee object contains a UnionAffiliation object, that employee must pay the dues and service charges that are recorded in that UnionAffiliation object.

This use of these patterns makes this system conform well to the Open/Closed Principle (OCP). The Employee class is closed against changes in payment method, payment classification, and union affiliation. New methods, classifications, and affiliations can be added to the system without affecting Employee.

Figure 26-6 is becoming our core model, or architecture. It's at the heart of everything that the payroll system does. There will be many other classes and designs in the payroll application, but they will all be secondary to this fundamental structure. Of course, this structure is not cast in stone. We will be modifying it along with everything else.

Payday

Use Case 7: Run the Payroll for Today

On receipt of 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. An audit-trail report is printed showing the action taken for each employee.

Payday <date>



Although it is easy to understand the intent of this use case, it is not so simple to determine what impact it has on the static structure of Figure 26-6. We need to answer several questions.

First, how does the Employee object know how to calculate its pay? Certainly, the system must tally up an hourly employee's time cards and multiply by the hourly rate. Similarly, the system must tally up a commissioned employee's sales receipts, multiply by the commission rate, and add the base salary. But where does this get done? The ideal place seems to be in the PaymentClassification derivatives. These objects maintain the records needed to calculate pay, so they should probably have the methods for determining pay. Figure 26-7 shows a collaboration diagram that describes how this might work.

Figure 26-7. Calculating an employee's pay


When asked to calculate pay, the Employee object refers this request to its PaymentClassification object. The algorithm used depends on the type of PaymentClassification that the Employee object contains. Figures 26-8 through 26-10 show the three possible scenarios.

Figure 26-8. Calculating an hourly employee's pay


Figure 26-9. Calculating a commissioned employee's pay


Figure 26-10. Calculating a salaried employee's pay





Agile Principles, Patterns, and Practices in C#
Agile Principles, Patterns, and Practices in C#
ISBN: 0131857258
EAN: 2147483647
Year: 2006
Pages: 272

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net