12class Design Solution RPT
12class Design Solution RPT
12class Design Solution RPT
Version 2003
Mastering OOAD with UML Issue: v2003
Payroll System Class Design Solution Issue Date: February 2003
12class_design_solution_rpt.doc
Revision History
Date Issue Description Author
09/01/2000 V2000 Generate for beta Shawn Siemers
10/03/2000 V2000 Final release Shawn Siemers
01/14/2003 V2003 Final Release Alex Kutsick
Table of Contents
1. Exercise: Class Design 5
1.1 Exercise: Define Operations 5
1.2 Exercise: Define States 6
1.3 Exercise: Define Attributes 8
1.4 Exercise: Define Dependencies and Associations 10
1.4.1 Use-Case Realization - Run Payroll 10
1.4.1.1 Run Payroll (with ss interface) 10
1.4.1.2 Run Payroll (with Security) 11
1.4.1.3 Run Payroll (with Distribution) 11
1.4.1.4 Run Payroll (with OODBMS Persistency) 12
1.4.1.5 Run Payroll (with everything) 13
1.4.2 Use-Case Realization - Maintain Timecard 14
1.4.2.1 Maintain Timecard (with ss interface) 14
1.4.2.2 Maintain Timecard (with Security) 15
1.4.2.3 Maintain Timecard (with Distribution) 16
1.4.2.4 Maintain Timecard (with OODBMS Persistence) 17
1.4.2.5 Maintain Timecard (with everything) 18
1.4.3 Use-Case Realization - Login 18
1.4.3.1 Login 18
1.4.3.2 Login (with Security) 19
1.4.4 BankSystem 20
1.4.5 PrintService 21
1.4.6 ProjectManagementDatabase 22
1.5 Exercise: Define Generalizations 23
<<Interface>>
<<boundary>> <<control>>
0..1 direct deposits checks via IBankSystem
SystemClockInterface PayrollController
(from External System Interfaces)
(from Payroll) (from Payroll) 0..1
1 1 + runPayroll() 0..1
+ start() + deposit()
0..1
0..1
+paycheckPrinter
0..1
0..*
<<entity>> <<Interface>>
Employee IPrintService
(from Payroll Artifacts) (from External System Interfaces)
+ isPayday() : boolean + print(aPaycheck : Paycheck, onPrinter : string)
+ getPayAmount(forPayPeriod : PayPeriod) : float BankInformation
+ getPaymentMethod() : PaymentMethod 1 1 (from Payroll Artifacts)
+ getBankInfo() : BankInformation + name : string
# calculatePay() : float + routingNumber : string
+ add(theTimecard : Timecard)
+ getEmployeeID() : int 1 0..*
+generatedPaychecks
+ getTimecard(forPayPeriod : PayPeriod) : Timecard
+ add(thePaycheck : Paycheck) <<entity>>
1
+ getEmployeeName() : string 0..* Paycheck
(from Payroll Artifacts)
<<class>> + new(forAmount : float, forPayPeriod : PayPeriod) : Paycheck
+ getAmount() : float
0..* + getEmployee() : Employee
0..1
<<entity>>
Timecard
<<entity>> <<entity>> (from Payroll Artifacts)
HourlyEmployee SalariedEmployee + getTotalHours() : float
TimecardEntry
(from Payroll Artifacts) (from Payroll Artifacts) + updateTimecard(withTimecardEntry : TimecardEntry) 1 0..*
(from Payroll Artifacts)
+ getHourlyRate() : float + getAnnualSalary() : float <<class>> + new(forPayPeriod : PayPeriod) : Timecard
- dayOfWeek : Date
+ save() 1 - numHours : float
<<class>> + new()
<<entity>>
CommissionedEmployee
(from Payroll Artifacts) 1
+ getPurchaseOrders(forTimePeriod : PayPeriod) : POList 1
+ getCommissionRate() : float PayPeriod
1 (from Payroll Artifacts)
+ startDate : Date
+ endDate : Date
0..1 <<entity>>
POList
PurchaseOrder
(from Payroll Artifacts)
(from Payroll Artifacts)
1 0..*
+ get PO amount() : float
<<boundary>>
TimecardForm
(from Employee Activities)
# displayTimecard()
+ // enter hours for charge numbers()
# displayChargeCodes()
+ saveTimecard()
+ // maintain timecard()
1
1
<<control>>
TimecardController
<<Interface>>
(from Employee Activities)
+chargeNumSource IProjectManagementDatabase
+ getCurrentTimecard(forEmployee : Employee) : Timecard (from External System Interfaces)
+ getChargeNums() : ChargeNumList
0..* 0..1+ getChargeNumbers(criteria : String) : chargeNumList
+ updateTimecard(withEntry : TimecardEntry)
+ initialize()
<<class>> + new() : TimecardController
+ saveTimecard()
0..1 0..1
ChargeNumList
(from Payroll Artifacts)
+ create()
+ add()
+ delete()
1 0..1
+currentTimecard
<<entity>>
TimecardEntry
<<entity>> Timecard
(from Payroll Artifacts)
Employee 1 (from Payroll Artifacts)
0..* - dayOfWeek : Date
(from Payroll Artifacts) + getTotalHours() : float
- numHours : float
+ add(theTimecard : Timecard) + updateTimecard(withTimecardEntry : TimecardEntry) 1 0..*
+ getEmployeeID() : int <<class>> + new(forPayPeriod : PayPeriod) : Timecard
<<class>> + new()
+ save()
1
1
PayPeriod
(from Payroll Artifacts)
+ startDate : Date
+ endDate : Date
LoginForm
(from GUI Framework)
+ open()
+ enterUserName()
1 0..*# validateUserIDPassword() : boolean
Any User + enterPassword()
(from Use-Case Realizations) + logInUser()
fired Terminated
Salaried
hired[ commissioned ] quit
changed to commissioned
Retired
Commiss ioned
+paycheckPrinter
0..1
0..*
<<Interface>>
At this time,
<<entity>> IPrintService
PaymentMethod is
Employee (from External System Interfaces)
intended to be an
name : string enumerated type
employee id : int
social security number : int
address : string
+generatedPaychecks
phone number : string
email : string 1 0..*
payment method : PaymentMethod
1
<<entity>>
Paycheck
0..*
amount : float
0..1
<<entity>> <<entity>>
HourlyEmployee SalariedEmployee 0..* 1
hourlyRate : float annualSalary : float
PayPeriod
(from Payroll Artifacts)
1
1 + startDate : Date
<<entity>> + endDate : Date
Timecard
/ totalNumHours : float
<<entity>> 1 0..1 POList
CommissionedEmployee (from Payroll Artifacts)
commissionRate : float
1
0..*
<<entity>>
PurchaseOrder
amount : float
date : Date
<<boundary>>
TimecardForm
(from Employee Activities)
1
<<control>> <<Interface>>
TimecardController +chargeNumSource IProjectManagementDatabas
(from Employee Activities) (from External System Interfaces)
0..* 0..1
0..1
0..1
<<entity>> +currentTimecard
Employee 0..1
(from Payroll Artifacts) TimecardEntry
- name : string <<entity>> (from Payroll Artifacts)
1 1 0..*
- employee id : int 0..* Timecard - dayOfWeek : Date
- social security number : int (from Payroll Artifacts) - numHours : float
- address : string /- totalNumHours : float
- phone number : string <<class>> + new()
- email : string
- payment method : PaymentMethod
At this time, Date is
intended to be an
At this time,
abstract data type
PaymentMethod is
not being explicitly
intended to be an
modeled
enumerated type
LoginForm
(from GUI Framework)
1 0..1
+ runPayroll() Global + deposit(aPaycheck : Paycheck, intoBank : BankInformation)
+ start()
visibility
<<entity>>
Employee
(from Payroll Artifacts)
<<Interface>>
IPrintService
- name : string
(from External System Interfaces)
- employee id : int Local visibility
- social security number : int (runPayroll())
+ print(aPaycheck : Paycheck, onPrinter : string)
- address : string
- phone number : string Parameter
- email : string visibility BankInformation
- payment method : PaymentMethod (from Payroll Artifacts)
+ name : string
+ isPayday() : boolean 0..1 1 + routingNumber : string
+ getPayAmount(forPayPeriod : PayPeriod) : float
+ getPaymentMethod() : PaymentMethod <<entity>>
1
+ getBankInfo() : BankInformation Paycheck
0..*
# calculatePay() : float (from Payroll Artifacts)
+ add(theTimecard : Timecard) - amount : float
+ getEmployeeID() : int
+ getTimecard(forPayPeriod : PayPeriod) : Timecard <<class>> + new(forAmount : float, forPayPeriod : PayPeriod) : Paycheck
+ add(thePaycheck : Paycheck) + getAmount() : float
+ getEmployeeName() : string + getEmployee() : Employee
1
0..1
Parameter
<<entity>> <<entity>> visibility 1
HourlyEmployee SalariedEmployee
(from Payroll Artifacts) (from Payroll Artifacts) 0..* PayPeriod
(from Payroll Artifacts)
- hourlyRate : float - annualSalary : float
<<entity>> 1 + startDate : Date
Timecard 0..1
+ getHourlyRate() : float + getAnnualSalary() : float + endDate : Date
(from Payroll Artifacts)
/- totalNumHours : float
+ getTotalHours() : float
<<entity>> + updateTimecard(withTimecardEntry : TimecardEntry) TimecardEntry
CommissionedEmployee <<class>> + new(forPayPeriod : PayPeriod) : Timecard 0..* (from Payroll Artifacts)
(from Payroll Artifacts) + save() 1
- dayOfWeek : Date
- commissionRate : float - numHours : float
0..1
Parameter
POList <<bind>> visibility
List
(from Payroll Artifacts) PurchaseOrder
(from Base Reuse)
<<entity>>
PurchaseOrder
(from Payroll Artifacts)
- amount : float
- date : Date
+ get PO amount()
<<Interface>> UnicastRemoteObject
Global Naming. IPayrollController (from Server)
(from java.rmi) <<Interface>>
visibility (from Payroll)
# UnicastRemoteObject() IBankSystem
+ lookup() Remote + // run payroll() + clone() (from External System Interfaces)
+ exportObject()
(from java.rmi)
+ deposit(aPaycheck : Paycheck, intoBank : BankInformation)
<<boundary>> Global
SystemClockInterface <<control>> visibility
PayrollController
(from Payroll)
start()
<<Interface>>
<<entity>> IPrintService
Employee (from External System Interfaces)
name : string
Local + print(aPaycheck : Paycheck, onPrinter : string)
employee id : int
social security number : int visibility
BankInformation
address : string
(from Payroll Artifacts)
phone number : string
email : string + name : string
payment method : PaymentMethod 1 + routingNumber : string
<<entity>> Parameter
<<entity>> <<entity>> Timecard visibility
HourlyEmployee SalariedEmployee / totalNumHours : float
hourlyRate : float annualSalary : float 1
getTotalHours() PayPeriod
getHourlyRate() getAnnualSalary() updateTimecard() (from Payroll Artifacts)
0..1
<<class>> new()
1 + startDate : Date
save()
+ endDate : Date
<<entity>>
CommissionedEmployee
1 0..1 POList <<bind>>
commissionRate : float List
(from Payroll Artifacts) PurchaseOrder (from Base Reuse)
getPurchaseOrders(forTimePeriod : PayPeriod) : POList
getCommissionRate() : float
<<entity>>
PurchaseOrder
(from Payroll Artifacts)
- amount : float
- date : Date
+ get PO amount()
<<control>>
<<boundary>>
SystemClockInterface PayrollController
(from Payroll)
Global
1 0..1 visibility
start()
+ runPayroll()
Global
visibility
PayrollDBManager <<Interface>>
Local IBankSystem
(from ObjectStore Support)
visibility (from External System Interfaces)
<<Interface>> Parameter
Parameter IPrintService visibility BankInformation
visibility <<entity>> (from External System Interfaces) (from Payroll Artifacts)
Employee + name : string
name : string + print(aPaycheck : Paycheck, onPrinter : string) + routingNumber : string
employee id : int 1
social security number : int
address : string
phone number : string <<entity>>
email : string 0..1 Paycheck
payment method : PaymentMethod amount : float
<<entity>> <<entity>>
HourlyEmployee SalariedEmployee
hourlyRate : float annualSalary : float Parameter
visibility
getHourlyRate() getAnnualSalary()
List
(from Base Reuse)
<<entity>>
CommissionedEmployee <<bind>>
commissionRate : float PurchaseOrder
1 <<entity>>
0..1 PurchaseOrder
getPurchaseOrders(forTimePeriod : PayPeriod) : POList POList
getCommissionRate() : float amount : float
(from Payroll Artifacts)
date : Date
get PO amount()
Naming.
(from java.rmi) <<Interface>>
Global
IPayrollController UnicastRemoteObject
visibility
+ lookup() (from Payroll) (from Server)
1 Global
<<Interface>>
Global visibility
IBankSystem
visibility <<control>> (from External System Interfaces)
0..1 PayrollController
(from Payroll) + deposit(aPaycheck : Paycheck, intoBank : BankInformation)
PayrollDBManager
(from ObjectStore Support)
+ runPayroll()
+ save() <<Interface>>
+ getTimecard() IPrintService
+ getEmployee() (from External System Interfaces)
BankInformation
(from Payroll Artifacts)
+ print(aPaycheck : Paycheck, onPrinter : string) + name : string
<<entity>> + routingNumber : string
Employee
1
name : string
employee id : int Local
social security number : int visibility
address : string
Parameter
phone number : string
visibility
email : string
payment method : PaymentMethod 0..1
getTotalHours() 0..1
<<entity>> updateTimecard()
<<entity>>
HourlyEmployee <<class>> new()
SalariedEmployee Parameter
save()
hourlyRate : float annualSalary : float visibility
getHourlyRate() getAnnualSalary()
List
<<entity>> <<bind>>
POList (from Base Reuse)
CommissionedEmployee PurchaseOrder
(from Payroll Artifacts)
commissionRate : float
1 0..1
<<entity>>
getPurchaseOrders()
PurchaseOrder
getCommissionRate()
(from Payroll Artifacts)
- amount : float
- date : Date
+ get PO amount()
<<boundary>>
TimecardForm
(from Employee Activities)
# displayTimecard()
<<class>> + new(forUser : ISecureUser) : TimecardForm ChargeNumList
(from Payroll Artifacts)
+ // enter hours for charge numbers()
# displayChargeCodes()
+ saveTimecard() + create()
+ // maintain timecard() + add()
+ delete()
1
1
<<control>>
Parameter
TimecardController <<Interface>>
visibility
(from Employee Activities)
IProjectManagementDatabase
(from External System Interfaces)
+ getCurrentTimecard(forEmployee : Employee) : Timecard
+ getChargeNums() : ChargeNumList + getChargeNumbers(criteria : String) : chargeNumList
+ updateTimecard(withEntry : TimecardEntry) + initialize()
<<class>> + new() : TimecardController Global
+ saveTimecard() visibility
0..1 0..1
+currentTimecard
TimecardEntry 0..1
(from Payroll Artifacts)
- dayOfWeek : Date <<entity>>
- numHours : float Timecard
1 (from Payroll Artifacts)
0..*
<<class>> + new() 1 /- totalNumHours : float
<<boundary>>
TimecardForm
(from Employee Activities)
MainEmployeeForm
(from Employee Activities) # displayTimecard()
<<class>> + new()
1 0..1
+ // maintain timecard() + // enter hours for charge numbers()
# displayChargeCodes()
+ saveTimecard()
+ // maintain timecard() <<entity>>
1 Employee
(from Payroll Artifacts)
- employee id : int
1
<<control>> 1 + add(theTimecard : Timecard)
TimecardController
0..1
(from Employee Activities) 1
Parameter
+ getCurrentTimecard(forEmployee : Employee) : Timecard visibility TimecardEntry
+ getChargeNums() : ChargeNumList (from Payroll Artifacts)
<<boundary>> Global
TimecardForm visibility
(from Employee Activities)
Naming.
Distributed
# displayTimecard() (from java.rmi)
class client
<<class>> + new(forUser : ISecureUser) : TimecardForm
+ // enter hours for charge numbers() + lookup()
# displayChargeCodes()
+ saveTimecard()
+ // maintain timecard()
1
1
<<Interface>>
ITimecardController
(from Employee Activities) UnicastRemoteObject
1 TimecardController
(from Server)
is distributed
+ // get current timecard()
+ // get charge codes() # UnicastRemoteObject()
+ // update timecard() + clone()
+ // setSession() Remote + exportObject()
+ // create() (from java.rmi) 1
+ // save timecard()
<<control>>
TimecardController <<entity>>
(from Employee Activities)
Employee
(from Payroll Artifacts)
+ getCurrentTimecard(forEmployee : Employee) : Timecard - employee id : int
+ getChargeNums() : ChargeNumList 0..1 1
+ updateTimecard(withEntry : TimecardEntry) + add(theTimecard : Timecard)
<<class>> + new() : TimecardController 1
Global + saveTimecard()
visibility +currentTimecard
0..1 0..*
1
Serializable
ChargeNumList
(from Payroll Artifacts) (from java.io)
0..*
+ create()
+ add() TimecardEntry
+ delete() (from Payroll Artifacts)
- dayOfWeek : Date Timecard,
- numHours : float TimecardEntry, and
ChargeNumList
<<class>> + new() must be passed
between distributed
objects
<<boundary>>
TimecardForm
(from Employee Activities)
# displayTimecard()
<<class>> + new(forUser : ISecureUser) : TimecardForm PayrollDBManager
+ // enter hours for charge numbers() (from ObjectStore Support)
# displayChargeCodes()
+ saveTimecard() + save(theTimecard : Timecard, forEmployee : Employee)
1 + getTimecard(forEmployee : Employee, forPayPeriod : PayPeriod) : Timecard
Global
visibility
1
<<control>>
<<entity>>
TimecardController
Employee
(from Employee Activities)
(from Payroll Artifacts)
1
+ getCurrentTimecard(forEmployee : Employee) : Timecard 0..1
+ getChargeNums() : ChargeNumList 1
+ updateTimecard(withEntry : TimecardEntry) TimecardEntry Parameter
<<class>> + new() : TimecardController (from Payroll Artifacts) visibility
+ saveTimecard() - dayOfWeek : Date
Global - numHours : float
visibility 0..1
<<class>> + new()
PayPeriod
(from Payroll Artifacts)
+currentTimecard 0..*
<<Interface>> 1 + startDate : Date
IProjectManagementDatabase 0..1 + endDate : Date
Parameter 1
(from External System Interfaces) 0..*
visibility 0..1
<<entity>>
+ getChargeNumbers(criteria : String) : chargeNumList Timecard
(from Payroll Artifacts)
+ initialize()
/- totalNumHours : float
Timecard
needs to be
secure
Parameter
ISecureData
visibility
(from Secure Interfaces)
1.4.3.1 Login
Login - VOPC
LoginForm
(from GUI Framework)
+ open()
+ enterUserName()
# validateUserIDPassword() : boolean
+ enterPassword()
+ logInUser()
# setupSecurityContext()
+ getUserContext() : ISecureUser
LoginForm
(from GUI Framework)
+ open()
+ enterUserName()
# validateUserIDPassword() : boolean
+ enterPassword()
+ logInUser()
# setupSecurityContext()
+ getUserContext() : ISecureUser
0..1
0..1
MainApplicationForm
(from GUI Framework) 1
+ start()
+ setupSecurityContext()
1
+ displayAvailOperations()
0..1
0..1
<<Interface>>
ISecureUser
(from Secure Interfaces)
MainEmployeeForm
(from Employee Activities) + setAccess(toData : ISecureData, access : SecurityAccess
+ getAccess(toData : ISecureData) : SecurityAccess
+ // maintain timecard() + getUserId() : UniqueId
+ new(forUser : UserID)
SecurityAccess
(from Secure Interfaces)
- CanRead : Boolean Parameter
- CanWrite : Boolean visibility
- CanDelete : Boolean
+ isReadable()
+ isWriteable()
+ isDeleteable()
+ makeReadable()
+ makeWriteable()
+ makeDeleteable()
+ new()
1.4.4 BankSystem
Main
Unless otherwise noted, all relationships are field visibility, and List will be used for
all relationships with a multiplicity greater than one.
<<Interface>>
IBankSystem
(from External System Interfaces)
<<entity>>
+ deposit(aPaycheck : Paycheck, intoBank : BankInformation) Paycheck
(from Payroll Artifacts)
<<subsystem proxy>>
BankSystem
Local
0..*
visibility
BankSystemInterface
+ submit(theTransaction : BankTransaction)
BankTransaction
Parameter - amount : float
visibility - transactionOperation : BankOperation
- routingNumber : String
+ create()
1.4.5 PrintService
Main
Unless otherwise noted, all relationships are field visibility, and List will be used for
all relationships with a multiplicity greater than one.
<<Interface>>
IPrintService
(from External System Interfaces)
<<subsystem proxy>>
PrinterInterface
PrintService
1 0..* + // print(theImage)
+ print(aPaycheck : Paycheck, onPrinter : String)
Parameter
Parameter visibility
visibility
For every printer the
Local PrinterImage
system must
visibility communicate with, a
(print()) PrinterInterface,
PrinterImage, and a
PaycheckPrinterImage
PaycheckPrinterImage
class must be defined
+ // create(fromPaycheck : Paycheck)
+ // buildPrintImage()
Local
visibility
(create())
<<entity>>
<<entity>>
Paycheck
(from Payroll Artifacts)
Employee
(from Payroll Artifacts)
- amount : float
- employee id : int
1
0..*
<<class>> + new(forAmount : float, forPayPeriod : PayPeriod) : Paycheck
+ getEmployeeID() : int
+ getAmount() : float
+ getEmployee() : Employee
0..1 1
PayPeriod
(from Payroll Artifacts)
+ startDate : Date
+ endDate : Date
1.4.6 ProjectManagementDatabase
Main
<<Interface>> A "plural" DBClass was defined
IProjectManagementDatabase because the charge numbers
(from External System
I t f ) always are retrieved as a set (a
list of the available charge
+ getChargeNumbers(criteria : String) : chargeNumList numbers).
+ initialize()
<<subsystem proxy>>
ProjectManagementDatabase Global
DBChargeNumbers visibility
+ getChargeNumbers(criteria : String) : chargeNumList
+ initialize() 1 1 + getChargeNums(criteria : string) : ChargeNumList
+ initialize()
1 1 DriverManager
1
(from java.sql)
+ create() Connection
+ add(aChargeNum : ChargeNum) (from java.sql)
+ delete(aChargeNum : ChargeNum)
1 Parameter
+ createStatement() : Statement visibility
Local
0..* visibility
0..*
ChargeNum
(from Payroll Artifacts)
- projectName : string
- value : string Parameter
visibility
+ getProjectName() : string
+ getValue() : string Statement
+ create(projectName, value) (from java.sql)
+ getString() : string
+ isPayday()
+ getPayAmount() 0..1 Address
+ getPaymentMethod() +homeAddress + street : string 1 0..1 PickUpMethod
# calculatePay() 0..1 + city : string +mailingAddress MailMethod DirectDepositMethod - thePrinter : string
+ add() 1 + state : string
+ getEmployeeID() + country : s tring
+ getTimecard() + zipCode : string 1 0..1 0..1
+returnAddress
+ add()
+ getEmployeeName()
+ getClassification() 1 1
1 <<Int erface>>
BankInformation IPrintService
+ name : s tring (from External System Interfaces)
+ routingNumber : string
+ print(aPaycheck : Paycheck, onPrinter : string)
0..* + printMailingLabel(toAddress : Address, fromAddress : Address)
<<entity>>
Timecard <<Interface>>
/- totalNumHours : float IBankSystem
(from External System Interfaces)
+ get TotalHours()
+ updateTimecard() + deposit(aPaycheck : Paycheck, intoBank : BankInformation)
<<clas s>> + new()
+ save()
0.. * <<entity>>
Paycheck
<<entity>>
Employee
- name : string
- employee id : int
- social security number : int
- phone number : string <<entity>>
- email : string Timecard
/ - totalNumHours : float
+ isPayday()
+ getPayAmount() + get TotalHours()
1 0..*
+ getPaymentMethod() + updat eTimecard()
# calculatePay() <<class>> + new()
+ add() + save()
+ getEmployeeID()
+ getTimecard()
+ add()
+ getEmployeeName()
+ getClassification()
0..1
1
EmpClassification
<<entity>> <<entity>>
HourlyClassification SalariedClass ific ation
- hourlyRate : float - annualSalary : float
List
+ getHourlyRate() (f ro m Base Reuse)
+ getAnnualSalary()
PurchaseOrder
<<entity>> <<bind>>
CommissionedClassification
- commissionRate : float POList
1 0..1
+ getPurchaseOrders()
+ getCommissionRate()
<<entity>>
PurchaseOrder
- amount : float
- date : Date
+ get PO amount ()
This required certain changes to the design, the most notable of which is the introduction of a dependency from the
Payroll Artifacts package to the External System Interfaces package. While this may seem strange, it is required in
order to allow the new payment method classes to execute themselves (i.e. to access the external systems).
This is an example where a design trade-off was made – smarter, more encapsulated payment method classes at the
expense of non-circular package dependencies. Of course, the packages and their contents could be adjusted to
eliminate the cycles (pull the class definitions needed by the External System Interfaces and place them in their own
package that the External System Interfaces and Payroll Artifacts package are dependent on. This was not done in
this example.
The use of “smarter” payment method classes simplifies the Run Payroll use-case realization as the
PayrollController no longer needs to know how to execute the different payment methods.
The use of the EmployeeClassification class means that, depending on the type of Employee that is being paid,
different pieces of information are extracted.
These changes are reflected in the following updated version of the Run Payroll use-case realization diagrams, as
well as some additional interaction diagrams that model the collaborations required for the PaymentMethod::pay()
operation:
1. start( )
1.1. runPayroll( )
For all timecards
1.1.1. isPayday( ) for the specified
pay period
1.1.2. getPayAmount(PayPeriod)
1.1.2.1. getTotalHours( )
Commissioned
[EmpClassification is CommissionedClassification ] employees also need
For all POs for the 1.1.2.2. getPurchaseOrders(PayPeriod) to retrieve POs
Perform these steps specified pay period
for each employee 1.1.2.3. get PO amount( )
1.1.2.4. calculatePay( )
In the future, additional calculations may be needed to calculate the Employee's take-home pay.
These calculations would be inserted here.
1.1.3. new(float, PayPeriod)
1.1.5. getPaymentMethod( )
: SystemClockInterface
1. start( )
: Employee
1.1.2.1. getTotalHours( )
: :
PurchaseOrder Timecard
<<boundary>> <<control>>
SystemClockInterface PayrollController
(from Payroll) (from Payroll)
1 0..1
+ start() + runPayroll()
<<entity>>
Employee
(from Payroll Artifacts)
<<entity>>
+ isPayday() : boolean 0..1 1+ pay() Paycheck
+ getPayAmount(forPayPeriod : PayPeriod) : float (from Payroll Artifacts)
+ getPaymentMethod() : PaymentMethod 1
# calculatePay() : float 0..* - amount : float
+ add(theTimecard : Timecard) <<class>> + new(forAmount : float, forPayPeriod : PayPeriod) : Paycheck
+ getEmployeeID() : int + getAmount() : float
+ getTimecard(forPayPeriod : PayPeriod) : Timecard + getEmployee() : Employee
+ add(thePaycheck : Paycheck)
+ getEmployeeName() : string
+ getClassification() : EmpClassification
0..1 1
0..1
1
EmpClassification
(from Payroll Artifacts) Parameter
visibility 1
0..*
PayPeriod
<<entity>> <<entity>> (from Payroll Artifacts)
HourlyClassification SalariedClassification <<entity>> 1 + startDate : Date
(from Payroll Artifacts) (from Payroll Artifacts) Timecard 0..1 + endDate : Date
- hourlyRate : float - annualSalary : float (from Payroll Artifacts)
/- totalNumHours : float
+ getHourlyRate() : float + getAnnualSalary() : float
+ getTotalHours() : float
+ updateTimecard(withTimecardEntry : TimecardEntry) TimecardEntry
<<class>> + new(forPayPeriod : PayPeriod) : Timecard 0..* (from Payroll Artifacts)
<<entity>> + save() 1
CommissionedClassification - dayOfWeek : Date
(from Payroll Artifacts) - numHours : float
- commissionRate : float
<<class>> + new()
+ getPurchaseOrders(forTimePeriod : PayPeriod) : POList
+ getCommissionRate() : float
1
Parameter
0..1 visibility
Local visibility
(getPayAmount()) <<entity>>
PurchaseOrder
(from Payroll Artifacts)
- amount : float
- date : Date
+ get PO amount()
In the future, additional calculations may be needed to calculate the Employee's take-home pay.
These calculations would be inserted here.
1.2.4. add(Paycheck)
Create a Paycheck for the
specified amount for the
Employee
1.2.5. getPaymentMethod( )
Execute the
Employee's
PaymentMethod 1.2.6. pay(Paycheck)
1. start( )
:
1.2. 6. pay(Paycheck) 1.2.2.3. get PO amount( ) Commiss ionedClassification
1.2.3. new(float, PayPeriod)
:
Paycheck
: PaymentMethod
: System Clock :
PurchaseOrder
Global # UnicastRemoteObject()
Naming.
visibility (from java.rmi) + clone() Serializable
Remote + exportObject()
(from java.io)
(from java.rmi)
+ lookup() <<control>>
PayrollController
(from Payroll)
<<boundary>> <<Interface>>
SystemClockInterface IPayrollController + runPayroll()
(from Payroll) (from Payroll)
<<entity>>
Employee PaymentMethod
(from Payroll Artifacts) Local <<entity>>
(from Payroll Artifacts)
visibility Paycheck
- name : string (from Payroll Artifacts)
- employee id : int + pay()
- social security number : int 1 - amount : float
- phone number : string
- email : string <<class>> + new(forAmount : float, forPayPeriod : PayPeriod) : Payc
0..1 0..* + getAmount() : float
+ isPayday() : boolean + getEmployee() : Employee
1
+ getPayAmount(forPayPeriod : PayPeriod) : float 1
+ getPaymentMethod() : PaymentMethod <<entity>> 0..1
# calculatePay() : float Timecard
0..* (from Payroll Artifacts)
+ add(theTimecard : Timecard)
+ getEmployeeID() : int /- totalNumHours : float
+ getTimecard(forPayPeriod : PayPeriod) : Timecard
+ add(thePaycheck : Paycheck) + getTotalHours()
+ getEmployeeName() : string + updateTimecard()
+ getClassification() : EmpClassification <<class>> + new()
0..1 + save()
1 0..1
EmpClassification
(from Payroll Artifacts)
1 1
PayPeriod
(from Payroll Artifacts)
<<entity>> <<entity>> Parameter
HourlyClassification SalariedClassification + startDate : Date
visibility
(from Payroll Artifacts) (from Payroll Artifacts) + endDate : Date
- hourlyRate : float - annualSalary : float
+ getHourlyRate() + getAnnualSalary()
<<entity>>
CommissionedClassification
(from Payroll Artifacts) 1 0..1 POList <<bind>>
List
- commissionRate : float (from Payroll Artifacts) PurchaseOrder (from Base Reuse)
<<entity>>
Local visibility PurchaseOrder
(from Payroll Artifacts)
((getPayAmount())
- amount : float
- date : Date
+ get PO amount()
1.1.3. getPayAmount(PayPeriod)
For all timecards
Perform these steps for the specified
for each employee 1.1.3.1. getTotalHours( )
pay period
[EmpClassification is CommissionedClassification ]
1.1.3.2. getPurchaseOrders(PayPeriod)
For all POs for the
specified pay period
1.1.3.3. get PO amount( )
Commissioned
1.1.3.4. calculatePay( )
employees also need
to retrieve POs
In the future, additional calculations may be needed to calculate the Employee's take-home pay.
These calculations would be inserted here.
Sequence Diagram:
Payroll Artifacts /
PaymentMethod::pay
:
1.1.3.4. calculatePay( ) Timecard
1.1.3.1. getTotalHours( )
1.1.2. isPayday( )
1.1.3. getPayAmount(PayPeriod)
1.1. 5. add(Paycheck)
1.1. runPayroll( ) 1.1.7. get PaymentMethod( )
1. start( ): Sy stemCloc kInterface : PayrollController : Employee 1.1.3.2. getPurchaseOrders(PayPeriod)
:
Commis sionedClass ific ation
: System Clock 1.1.4. new(float, PayPeriod)
1.1.3.3. get PO amount( )
1.1.8. pay(Paycheck)
1.1.1. getEmployee(string) :
1.1.6. save(Paycheck, Employee) Paycheck
:
PurchaseOrder
: PaymentMethod : PayrollDBManager
<<boundary>> <<control>>
SystemClockInterface PayrollController
(from Payroll)
Global
1 0..1 visibility
start()
+ runPayroll()
Global
visibility
PayrollDBManager <<Interface>>
(from ObjectStore Support) IBankSystem
(from External System Interfaces)
Local
+ save(theTimecard : Timecard, forEmployee : Employee) visibility
+ getTimecard(forEmployee : Employee, forPayPeriod : PayPeriod) : Timecard + deposit(aPaycheck : Paycheck, intoBank : BankInformation)
+ getEmployee(withID : string) : Employee
Parameter
visibility
<<entity>>
SalariedClassification
<<entity>> annualSalary : float
HourlyClassification
List
hourlyRate : float getAnnualSalary() (from Base Reuse)
getHourlyRate()
<<bind>>
PurchaseOrder
<<entity>> <<entity>>
CommissionedClassification PurchaseOrder
1 0..1 POList
commissionRate : float amount : float
(from Payroll Artifacts)
date : Date
getPurchaseOrders(forTimePeriod : PayPeriod) : POList
getCommissionRate() : float get PO amount()
[EmpClassification is CommissionedClassification ]
For all POs for the
specified pay period 1.2.3.2. getPurchaseOrders(PayPeriod)
1.2.3.4. calculatePay( )
In the future, additional calculations may be needed to calculate the Employee's take-home pay.
These calculations would be inserted here.
Create a new
paycheck for the
employee 1.2.4. new(float, PayPeriod)
containing the
calculated pay.
1.2.5. add(Paycheck)
Sequence Diagram:
OODBMS Support /
1.2.6. save(Paycheck, Employee) PayrollDBManager -
Save Paycheck
Execute the 1.2.7. getPaymentMethod( )
Employee's 1.2.8. pay(Paycheck)
PaymentMethod
: PayrollDBManager
Naming. # UnicastRemoteObject()
(from java.rmi) Remote + clone()
Local + exportObject()
Global (from java.rmi)
+ lookup() visibility
visibility <<Interface>>
<<control>>
IPayrollController
PayrollController
(from Payroll)
<<boundary>> (from Payroll)
SystemClockInterface
+ // run payroll() Serializable
+ runPayroll()
start() (from java.io)
PayrollDBManager Local
(from ObjectStore Support) visibility
Global
+ save() visibility Parameter
+ getTimecard() visibility
+ getEmployee()
Parameter
visibility
PaymentMethod
(from Payroll Artifacts)
<<entity>>
+ pay()
Employee
name : string 1 <<entity>>
employee id : int 0..1 Paycheck
social security number : int
amount : float
phone number : string
email : string
<<class>> new(forAmount : float, forPayPeriod : PayPeriod) : Paycheck
getAmount() : float
isPayday() : boolean 0..*
1 getEmployee() : Employee
getPayAmount(forPayPeriod : PayPeriod) : float
getPaymentMethod() : PaymentMethod
1 0..1
calculatePay() : float
add(theTimecard : Timecard) <<entity>>
0..* Timecard
getEmployeeID() : int
getTimecard(forPayPeriod : PayPeriod) : Timecard / totalNumHours : float
add(thePaycheck : Paycheck)
getEmployeeName() : string getTotalHours()
getClassification() : EmpClassification updateTimecard()
0..1 <<class>> new()
save()
1
EmpClassification 0..1
(from Payroll Artifacts)
<<entity>> <<entity>>
HourlyClassification SalariedClassification
Parameter 1
hourlyRate : float annualSalary : float visibility 1
PayPeriod
getHourlyRate() getAnnualSalary() (from Payroll Artifacts)
+ startDate : Date
+ endDate : Date
<<entity>>
CommissionedClassification
commissionRate : float
getPurchaseOrders()
getCommissionRate()
1
<<entity>>
0..1 PurchaseOrder
POList (from Payroll Artifacts)
List
PurchaseOrder (from Payroll Artifacts) - amount : float
(from Base Reuse)
<<bind>> - date : Date
+ get PO amount()
PaymentMethod::pay
Sequence Diagram:
[ PaymentMethod was DirectDepositMethod]
IBankSystem /
1. pay(Paycheck) IBankSystem::deposit
Sequence Diagram:
IPrintService /
IPrintService::print
PaymentMethod::pay
3. pay(Paycheck)
PaymentMet : MailMethod 3.1. print(Paycheck, string)
hodClient 3.2. printMailingLabel(Address, Address)
2. pay(Paycheck)
:
IP rintService
2.1. print(Paycheck, string)
:
1. pay(Paycheck)
PickUpMethod