Software Design and Construction 1 SOFT2201 / COMP9201
Self Learning Case Study: Next Gen POS design with GRASP
School of Computer Science
The University of Sydney
Page 1
Copyright warning
COMMONWEALTH OF AUSTRALIA Copyright Regulations 1969 WARNING
This material has been reproduced and communicated to you by or on behalf of the University of Sydney
pursuant to Part VB of the Copyright Act 1968 (the Act).
The material in this communication may be subject to copyright under the Act. Any further copying or communication of this material by you may be the subject of copyright protection under
the Act.
Do not remove this notice.
The University of Sydney Page 2
Use Case Realization
– “…describes how a particular use case is realized within the design model, in terms of collaborating objects” [RUP]
– Individual scenarios are realized
Use case -> System events -> System sequence diagram ->
System operation contracts -> Interaction diagrams -> Design classes
The University of Sydney Page 3
System Sequence Diagram
The University of Sydney
Page 4
loop
: Cashier
[ more items ]
Process Sale Scenario
makeNewSale()
enterItem(itemID, quantity)
description, total
endSale() total with taxes
makePayment(amount) change due, receipt
:System
these input system events invoke system operations
the system event enterItem invokes a system operation called enterItem and so forth
this is the same as in object- oriented programming when we say the message foo invokes the method (handling operation) foo
System operation
– The system operations in the SSD are used as the start messages into the domain layer
– If communication diagrams are used, one per system operation
– Same for sequence diagram
.. .
makeNewSale
enterItem
endSale
makePayment
DOMAIN LAYER
:Register
:Register
:Register
1: ???
1: ???
1: ???
1: ???
The University of Sydney
Page 5
Window objects or
GUI widget objects or
Web control objects
UI LAYER
makeNewSale, etc., are the system operations from the SSD
each major interaction diagram starts with a system operation going into a domain layer controller object, such as Register
:Register
One Diagram Per System Operation
Window objects or
GUI widget objects or
Web control objects
makeNewSale
.. .
create
: Register
: Sale
: Register
: ProductCatalog
enterItem(…)
desc = getProductDesc( itemID )
…
The University of Sydney
Page 6
UI LAYER
DOMAIN LAYER
Design makeNewSale
– Choosing the controller class
– Afaçadecontrollerissatisfactoryifthereareonlyafewsystemoperations – Use Register here
– Creating a new Sale
– RegistercreatesSale
• Register “records” sale
– Sale creates a collection to store SalesLineItems
The University of Sydney
Page 7
Design makeNewSale
The University of Sydney
Page 8
by Creator and Controller
makeNewSale
Register creates a Sale by Creator
by Creator, Sale creates an empty collection (such as a List) which will eventually hold SalesLineItem instances
lineItems : List
this execution specification is implied to be within the constructor of the Sale instance
:Register
create
:Sale
create
Design: enterItem
The University of Sydney Page 9
Design enterItem
– Choosing controller class
– Display item description and price (ignore at this stage)
– Create a new SalesLineItem
– Finding a ProductDescription
– Visibility to ProductCatalog
– Temporary and persistent storage
– We can defer database design and use temporary memory object instead
The University of Sydney
Page 10
Design enterItem by Controller
by Creator
enterItem(id, qty)
1: desc = getProductDesc(id)
by Expert
2: makeLineItem(desc, qty)
:Sale
2.1: create(desc, qty)
:Product Catalog
1.1: desc = get(id)
: Map
2.2: add(sl)
The University of Sydney
Page 11
:Register
lineItems : List
sl: SalesLineItem
add the newly created SalesLineItem instance to the List
Partial Design Class Diagram
descriptions {Map}
1
1
…
getProductDesc(…)
ProductDescription
ProductCatalog
description : Text price : Money itemID: ItemID
1..*
catalog
Sale
…
description
Register
isComplete : Boolean time : DateTime
lineItems currentSale {ordered}
SalesLineItem
…
quantity : Integer
enterItem(…) …
makeLineItem(…) …
…
The University of Sydney
Page 12
1
1..*
Design makePayment
The University of Sydney Page 13
Design makePayment – Creating Payment instance
– How should we assignment responsibilities of creating Payment instance and associate it with the Sale
Payment
Sale
The University of Sydney Page 14
Register
Options
makePayment()
1: create()
2: addPayment(p)
1: makePayment()
1.1. create()
: Register
p : Payment
:Sale
makePayment()
: Register
:Sale
The University of Sydney
Page 15
:Payment
–
Final Solution
Creating payment
by Controller
makePayment(cashTendered)
:Register
by Creator and Low Coupling
1: makePayment(cashTendered) :Sale
1.1: create(cashTendered)
:Payment
The University of Sydney
Page 16
Design makePayment
Sale
– Logging a sale
…
…
…
…
Sale
Logs-completed5
** Logs-completed5
11
Store
…
addSale(s : Sale) …
SalesLedger
…
addSale(s : Sale) …
The University of Sydney
Page 17
Store is responsible for knowing and adding completed Sales.
Acceptable in early development cycles if the Store has few responsibilities.
SalesLedger is responsible for knowing and adding completed Sales.
Suitable when the design grows and the Store becomes uncohesive.
Design makePayment makePayment(cashTendered)
1: makePayment(cashTendered)
1.1: create(cashTendered)
note that the Sale instance is named ‘s’ so that it can be referenced as a parameter in messages 2 and 2.1
:Register
s :Sale
by Expert
2: addSale(s)
2.1: add(s)
:Payment
:Store
The University of Sydney
Page 18
completedSales: List
Design makePayment
– Calculating the balance
– Who is responsible for knowing the balance?
• To calculate, sale total and payment tendered are required
• Sale and Payment are partial Experts – Consider coupling…
• Sale already has visibility into Payment
• Payment does not have visibility into Sale
• Giving Sale primary responsibility doesn’t increase overall coupling
The University of Sydney Page 19
getBalance design
{ bal = pmt.amount – s.total } bal = getBalance
1: amt = getAmount
s :Sale
pmt: Payment
The University of Sydney
Page 20
2: t = getTotal
From UI to Domain Layer
presses button
: Cashier
UI Layer
Domain Layer
actionPerformed( actionEvent )
:SaleJFrame
enterItem(itemID, qty)
: ???
system operation message
Which class of object should be responsible for receiving this system event message?
It is sometimes called the controller or coordinator. It does not normally do the work, but delegates it to other objects.
The controller is a kind of “facade” onto the domain layer from the interface layer.
The University of Sydney
Page 21
Less Desirable Coupling
presses button
Cashier
UI Layer
actionPerformed( actionEvent )
:SaleJFrame
It is undesirable for an interface layer object such as a window to get involved in deciding how to handle domain processes.
Business logic is embedded in the presentation layer, which is not useful.
Domain Layer
1: makeLineItem(itemID, qty)
The University of Sydney
Page 22
SaleJFrame should not send this message.
:Sale
Additional Self-study
Object Design: Initial System Operations
The University of Sydney Page 23
Object Design: startUp
– Initial system operation
– Delay until all other system operations have been considered
– What objects need to be there through out the use case
– What associations need to be there through out the use case
– Create a set of domain objects that need to be there to support the use case execution
– Find a suitable initial object and request that object to create a set of other objects
– Do the initialization design last
The University of Sydney Page 24
Create Initial Domain Object
The University of Sydney
Page 25
[Larman 2005] page 348
Designing Store.create()
– Create: Store, Register, ProductCatalog, ProductDescription
– Associate: ProductCatalog with ProductDescription; Store with ProductCatalog; Store with Register; Register with ProductCatalog
The University of Sydney Page 26
Designing Store.create()
pass a reference to the ProductCatalog to the Register, so that it has permanent visibility to it
create
by Creator
:Store
2: create(pc)
1.1: create 1.2.2*: put(id, pd)
:Register
create an empty collection object
descriptions: Map
1: create
pc: ProductCatalog
1.2: loadProdSpecs()
1.2.1*: create(id, price, description)
pd: ProductDescription
The University of Sydney
Page 27
the * in sequence number indicates the message occurs in a repeating section
Mapping Designs to Code
– Class and interface definition – Method definitions
The University of Sydney Page 28
Creating Class Definition from DCD
public class SalesLineItem {
private int quantity;
private ProductDescription description;
public SalesLineItem(ProductDescription desc, int qty) { … } public Money getSubtotal() { … }
}
SalesLineItem quantity : Integer getSubtotal() : Money
description
1
ProductDescription
description : Text price : Money itemID : ItemID
…
The University of Sydney
Page 29
Creating methods from interaction diagram
enterItem(id, qty)
1: desc = getProductDesc(id)
1.1: desc = get(id)
: Map
:Register
2: makeLineItem(desc, qty)
:Sale
2.1: create(desc, qty)
:Product Catalog
sl: SalesLineItem
2.2: add(sl)
The University of Sydney
Page 30
lineItems : List
The Register class
public class Register
{
private ProductCatalog catalog; private Sale currentSale;
public Register(ProductCatalog pc) {…}
public void endSale() {…}
public void enterItem(ItemID id, int qty) {…}
public void makeNewSale() {…}
public void makePayment(Money cashTendered) {…} }
catalog 1
currentSale
1
…
ProductCatalog
getProductDesc(…)
Sale
Register
isComplete : Boolean time : DateTime
…
The University of Sydney
Page 31
endSale()
enterItem(id: ItemID, qty : Integer) makeNewSale() makePayment(cashTendered : Money)
becomeComplete() makeLineItem(…) makePayment(…) getTotal()
Order of implementation
Store
address : Address name : Text
addSale(…)
7
1 ProductCatalog
… getProductDesc(…)
3
ProductDescription
description : Text price : Money itemID : ItemID
…
1
SalesLineItem quantity : Integer getSubtotal()
Payment
2
1
1..*
From least-coupled to most-coupled
1 6 Sale 5
Register …
endSale() enterItem(…) makeNewSale() makePayment(…)
isComplete : Boolean time : DateTime
becomeComplete() makeLineItem(…) makePayment(…) getTotal()
… *
4
1
1..*
1
amount : Money 1
…
The University of Sydney
Page 32