60-322 object-oriented analysis and design week 11, 2009
TRANSCRIPT
60-322 Object-Oriented Analysis and Design
Week 11, 2009
Mar 26, 2008 2
Ch 18. Use Case Realization for NextGen POS
: Cashier :System
Simple cash-only Process Sale scenario:
1. Customer arrives at a POS checkout with goods and/or services to purchase.2. Cashier starts a new sale.3. Cashier enters item identifier.4. System records sale line item and presents item description, price, and running total. Cashier repeats steps 3-4 until indicates done.5. System presents total with taxes calculated.6. Cashier tells Customer the total, and asks for payment.7. Customer pays and System handles payment....
enterItem(itemID, quantity)
endSale
makePayment(amount)
description, total
total with taxes
change due, receipt
makeNewSale
[ more items ]loop
Process Sale Scenario
Mar 26, 2008 3
Ch 18. Use Case Realization for NextGen POS
Register
id
ItemStore
nameaddress
Sale
dateTime/ total
CashPayment
amountTendered
SalesLineItem
quantity
Cashier
id
Customer
ProductCatalog
ProductDescription
itemIDdescriptionprice
Stocks
*
Houses
1..*
Used-by
*
Contains
1..*
Describes
*
Captured-on
Contained-in
1..*
Records-sale-of
0..1
Paid-by Is-for
Logs-completed
*
Works-on
1
1
1
1 1..*
1
1
1
1
1
1
1
0..1 1
1
Ledger
Records-accounts-
for
1
1
Mar 26, 2008 4
Ch 18. How to Design makeNewSale?
:Register
makeNewSale
:Salecreate
Register creates a Sale by Creator
create lineItems :List<SalesLineItem>
by Creator, Sale creates an empty collection (such as a List) which will eventually hold SalesLineItem instances
by Creator and Controller
this execution specification is implied to be within the constructor of the Sale instance
Register
id
ItemStore
nameaddress
Sale
dateTime/ total
CashPayment
amountTendered
SalesLineItem
quantity
Cashier
id
Customer
ProductCatalog
ProductDescription
itemIDdescriptionprice
Stocks
*
Houses
1..*
Used-by
*
Contains
1..*
Describes
*
Captured-on
Contained-in
1..*
Records-sale-of
0..1
Paid-by Is-for
Logs-completed
*
Works-on
1
1
1
1 1..*
1
1
1
1
1
1
1
0..1 1
1
Ledger
Records-accounts-
for
1
1
Mar 26, 2008 5
How to Design enterItem?
2: makeLineItem(desc, qty)enterItem(id, qty)
1: desc = getProductDesc(id) 2.1: create(desc, qty)
1.1: desc = get(id)
:Register :Sale
:ProductCatalog
sl: SalesLineItem
lineItems : List<SalesLineItem>
: Map<ProductDescription>
2.2: add(sl)
by Expert
by Controllerby Creator
add the newly created SalesLineItem instance to the List
Register
id
ItemStore
nameaddress
Sale
dateTime/ total
CashPayment
amountTendered
SalesLineItem
quantity
Cashier
id
Customer
ProductCatalog
ProductDescription
itemIDdescriptionprice
Stocks
*
Houses
1..*
Used-by
*
Contains
1..*
Describes
*
Captured-on
Contained-in
1..*
Records-sale-of
0..1
Paid-by Is-for
Logs-completed
*
Works-on
1
1
1
1 1..*
1
1
1
1
1
1
1
0..1 1
1
Ledger
Records-accounts-
for
1
1
Mar 26, 2008 6
How to Design enterItem?
SalesLineItem
quantity : Integer
...
ProductCatalog
...
getProductDesc(...)
ProductDescription
description : Textprice : MoneyitemID: ItemID
...
1..*
1..*
Register
...
enterItem(...)...
Sale
isComplete : Booleantime : DateTime
makeLineItem(...)...1
1
1
catalog
currentSale
descriptions{Map}
lineItems{ordered}
description
Mar 26, 2008 7
How to Design endSale
:RegisterendSale( s :Sale1: becomeComplete
by Expertby Controller
Mar 26, 2008 8
Ch 18. Use Case Realization for NextGen POS
: Cashier :System
Simple cash-only Process Sale scenario:
1. Customer arrives at a POS checkout with goods and/or services to purchase.2. Cashier starts a new sale.3. Cashier enters item identifier.4. System records sale line item and presents item description, price, and running total. Cashier repeats steps 3-4 until indicates done.5. System presents total with taxes calculated.6. Cashier tells Customer the total, and asks for payment.7. Customer pays and System handles payment....
enterItem(itemID, quantity)
endSale
makePayment(amount)
description, total
total with taxes
change due, receipt
makeNewSale
[ more items ]loop
Process Sale Scenario
Mar 26, 2008 9
How to Design getTotal()? : Cashier :System
Simple cash-only Process Sale scenario:
1. Customer arrives at a POS checkout with goods and/or services to purchase.2. Cashier starts a new sale.3. Cashier enters item identifier.4. System records sale line item and presents item description, price, and running total. Cashier repeats steps 3-4 until indicates done.5. System presents total with taxes calculated.6. Cashier tells Customer the total, and asks for payment.7. Customer pays and System handles payment....
enterItem(itemID, quantity)
endSale
makePayment(amount)
description, total
total with taxes
change due, receipt
makeNewSale
[ more items ]loop
Process Sale Scenario
:Saletot = getTotal 1 * [i = 1..n]: st = getSubtotal
:ProductDescription
1.1: pr = getPrice
lineItems[ i ]: SalesLineItem
by Expert by ExpertUML: note the selector notation to select elements from the lineItems collection
•Not all interaction diagrams start with a system operation message.•They can start with any message for which the designer wishes to show interactions.
Mar 26, 2008 10
Ch 18. Use Case Realization for NextGen POS
: Cashier :System
Simple cash-only Process Sale scenario:
1. Customer arrives at a POS checkout with goods and/or services to purchase.2. Cashier starts a new sale.3. Cashier enters item identifier.4. System records sale line item and presents item description, price, and running total. Cashier repeats steps 3-4 until indicates done.5. System presents total with taxes calculated.6. Cashier tells Customer the total, and asks for payment.7. Customer pays and System handles payment....
enterItem(itemID, quantity)
endSale
makePayment(amount)
description, total
total with taxes
change due, receipt
makeNewSale
[ more items ]loop
Process Sale Scenario
Mar 26, 2008 11
How to Design makePayment?
1: makePayment(cashTendered)
1.1: create(cashTendered)
:Register :Sale
:Payment
makePayment(cashTendered)
by Controller by Creator and Low Coupling
: Register p : Payment
:Sale
makePayment() 1: create()
2: addPayment(p)
Remember this? bad design!
Mar 26, 2008 12
Logging a Sale - How to Design makePayment?
Mar 26, 2008 13
Logging a Sale - How to Design makePayment?
Who is responsible for knowing all the logged sales and doing the logging?
Store or SalesLedger?
Store
...
addSale(s : Sale)...
SalesLedger
...
addSale(s : Sale)...
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.
Sale
...
...
Sale
...
...
Logs-completed Logs-completed
* *
1 1
Mar 26, 2008 14
Logging a Sale - How to Design makePayment?
Stick with Store for now, may change to SalesLedger later during desing?
1: makePayment(cashTendered)
1.1: create(cashTendered)
:Register s :Sale
:Payment
makePayment(cashTendered)
:Store
2: addSale(s)
completedSales: List<Sale>
2.1: add(s)
by Expert
note that the Sale instance is named's' so that it can be referenced as a parameter in messages 2 and 2.1
Mar 26, 2008 15
Calculating balance• The Process Sale use case implies that the balance due from a payment be printed on a receipt and displayed somehow.
•
• Because of the Model-View Separation principle, we should not concern ourselves with how the balance will be displayed or printed.
• But we must ensure that it is known.
•No class currently knows the balance, so we need to create a design of object interactions that satisfies this requirement.
Mar 26, 2008 16
Calculating balance – the Reasoning
s :Sale pmt: Payment1: amt = getAmountbal = getBalance
2: t = getTotal
{ bal = pmt.amount - s.total }
To calculate the balance, we need the sale total and payment cash tendered. Therefore, Sale and Payment are partial Experts on solving this problem.
If the Payment is primarily responsible for knowing the balance, it needs visibility to the Sale, to ask the Sale for its total. Since it does not currently know about the Sale, this approach would increase the overall coupling in the design - it would not support the Low Coupling pattern.
In contrast, if the Sale is primarily responsible for knowing the balance, it needs visibility to the Payment, to ask it for its cash tendered. Since the Sale already has visibility to the Payment -as its creator. This approach does not increase the overall coupling and is therefore a preferable design.
Mar 26, 2008 17
The Final NextGen DCD for Iteration -1
SalesLineItem
quantity : Integer
getSubtotal()
ProductCatalog
...
getProductDesc(...)
ProductDescription
description : Textprice : MoneyitemID: ItemID
...
Store
address : Addressname : Text
addCompleteSale(...)
Payment
amount : Money
...
1..*
1..*
Register
...
endSale()enterItem(...)makeNewSale()makePayment(...)
Sale
isComplete : Booleantime : DateTime
becomeComplete()makeLineItem(...)makePayment(...)getTotal()
1
1
1
1
1
1
*
catalog
catalog
register
currentSale
descriptions{Map}
lineItems{ordered}
payment
completedSales{ordered}
description
Mar 26, 2008 18
How to Connect the UI Layer to the Domain Layer?
Common designs by which objects in the UI layer obtain visibility to objects in the domain layer include the following:
– An initializer object (for example, a Factory object) called from the application starting method (e.g., the Java main method) creates both a UI and a domain object and passes the domain object to the UI.
– A UI object retrieves the domain object from a well-known source, such as a factory object that is responsible for creating domain objects.
Mar 26, 2008 19
Controller (in Coding)
Mar 26, 2008 20
How to Connect the UI Layer to the Domain Layer?
Once the UI object has a connection to the Register instance (the facade controller in this design), it can forward system event messages, such as the enterItem and endSale message
:Register
Cashier
:ProcessSaleJFrame
actionPerformed( actionEvent )
1: enterItem(id, qty)? system event
UILayer
DomainLayer
presses button
Mar 26, 2008 21
Initialization and the 'Start Up' Use Case
Most systems have either an implicit or explicit Start Up use case and some initial system operation related to the starting up of the application.
Although abstractly, a startUp system operation is the earliest one to execute, delay the development of an interaction diagram for it until after all other system operations have been considered.
This practice ensures that information has been discovered concerning the initialization activities required to support the later system operation interaction diagrams.
Mar 26, 2008 22
How do Applications Start Up? The startUp or initialize system operation of a Start Up use
case abstractly represents the initialization phase of execution when an application is launched.
To understand how to design an interaction diagram for this operation, you must first understand the contexts in which initialization can occur. How an application starts and initializes depends on the programming language and operating system.
In all cases, a common design idiom is to create an initial domain object or a set of peer initial domain objects that are the first software "domain" objects created.
This creation may happen explicitly in the starting main method or in a Factory object called from the main method.
Mar 26, 2008 23
How do Applications Start Up? Often, the initial domain object (assuming the
singular case), once created, is responsible for the creation of its direct child domain objects.
For example, a Store chosen as the initial domain object may be responsible for the creation of a Register object.
Mar 26, 2008 24
Choosing the Initial Domain Object
Guideline Choose as an initial domain object a class at or
near the root of the containment or aggregation hierarchy of domain objects. This may be a facade controller, such as Register, or some other object considered to contain all or most other objects, such as a Store.
In this application, we chose the Store as the initial object.
Mar 26, 2008 25
Choosing the Initial Domain Object
By reflecting on the prior interaction designs, we identify the following initialization work:
Create a Store, Register, ProductCatalog, and ProductDescriptions.
Associate the ProductCatalog with ProductDescriptions
Associate Store with ProductCatalog. Associate Store with Register. Associate Register with ProductCatalog.
Mar 26, 2008 26
Choosing the Initial Domain Object
:Store :Register
pc:ProductCatalog
create 2: create(pc)
1: create
1.2: loadProdSpecs()
descriptions:Map<ProductDescription>
1.1: create
1.2.2*: put(id, pd)
1.2.1*: create(id, price, description)
pd:ProductDescriptionthe * in sequence number indicates the
message occurs in a repeating section
pass a reference to the ProductCatalog to the Register, so that it has permanent visibility to it
by Creatorcreate an empty collection object
Mar 26, 2008 27
Process: Iterative and Evolutionary Object Design
The essential point:
Keep it light and short, move quickly to code and test, and don't try to detail everything in UML models. Model the creative, difficult parts of the design.
Mar 26, 2008 28
Ch 19. Designing For Visibility
Visibility is the ability of one object to see or have reference to another.
This chapter explores this basic but necessary design issue;
those new to object design sometimes don't think about and design to achieve necessary visibility.
Mar 26, 2008 29
Visibility Between Objects
Message are passing around among object……
For a sender object to send a message to a receiver object, the sender must be visible to the receiver - the sender must have some kind of reference or pointer to the receiver object.
Mar 26, 2008 30
Visibility Between Objects
When creating a design of interacting objects, it is necessary to ensure that the necessary visibility is present to support message interaction
: RegisterenterItem
(itemID, quantity)
: ProductCatalog
desc = getProductDesc( itemID )
public void enterItem( itemID, qty ){ ... desc = catalog.getProductDesc(itemID) ...}
class Register{ ... private ProductCatalog catalog; ...}
Mar 26, 2008 31
What is Visibility? In common usage, visibility is the ability of an
object to "see" or have a reference to another object.
More generally, it is related to the issue of scope: Is one resource (such as an instance) within the scope of another?
There are four common ways that visibility can be achieved from object A to object B:
Mar 26, 2008 32
What is Visibility? – Attribute visibility
B is an attribute of A.
– Parameter visibility B is a parameter of a method of A.
– Local visibility B is a (non-parameter) local object in a method of A.
– Global visibility B is in some way globally visible.
The motivation to consider visibility is this:For an object A to send a message to an object B, B must
be visible to A.
Mar 26, 2008 33
Attribute Visibility Attribute visibility from A to B exists when B is an
attribute of A. It is a relatively permanent visibility because it persists as long as
A and B exist. This is a very common form of visibility in object-
oriented systems.
: RegisterenterItem
(itemID, quantity)
: ProductCatalog
desc = getProductDesc( itemID )
public void enterItem(itemID, qty){ ... desc = catalog.getProductDesc(itemID) ...}
class Register{ ... private ProductCatalog catalog; ...}
Mar 26, 2008 34
Parameter Visibility Parameter visibility from A to B exists when B is
passed as a parameter to a method of A. It is a relatively temporary visibility because it persists only within
the scope of the method. After attribute visibility, it is the second most common form of visibility in object-oriented systems.
2: makeLineItem(desc, qty)enterItem(id, qty)
1: desc = getProductDesc(id)
2.1: create(desc, qty)
:Register :Sale
:ProductCatalog
sl : SalesLineItemmakeLineItem(ProductDescription desc, int qty){ ... sl = new SalesLineItem(desc, qty); ...}
Mar 26, 2008 35
Parameter Visibility It is common to transform parameter visibility into
attribute visibility.
2: makeLineItem(desc, qty)enterItem(id, qty)
2: desc = getProductDesc(id)
2.1: create(desc, qty)
:Register :Sale
:ProductCatalog
sl : SalesLineItem
// initializing method (e.g., a Java constructor)SalesLineItem(ProductDescription desc, int qty){ ...description = desc; // parameter to attribute visibility...}
Mar 26, 2008 36
Local Visibility
Local visibility from A to B exists when B is declared as a local object within a method of A.
It is a relatively temporary visibility because it persists only within the scope of the method. After parameter visibility, it is the third most common form of visibility in object-oriented systems.
Two common means by which local visibility is achieved are:
– Create a new local instance and assign it to a local variable.– Assign the returning object from a method invocation to a local
variable.
As with parameter visibility, it is common to transform locally declared visibility into attribute visibility.
Mar 26, 2008 37
Local Visibility
: RegisterenterItem
(itemID, quantity)
: ProductCatalog
desc = getProductDesc( itemID )
enterItem(id, qty){ ...// local visibility via assignment of returning objectProductDescription desc = catalog.getProductDes(id);...}
Mar 26, 2008 38
Global Visibility
Global visibility from A to B exists when B is global to A.
It is a relatively permanent visibility because it persists as long as A and B exist. It is the least common form of visibility in object-oriented systems.
One way to achieve global visibility is to assign an instance to a global variable, which is possible in some languages, such as C++, but not others, such as Java.
The preferred method to achieve global visibility is to use the Singleton pattern [ch 26], which is discussed in a later chapter.
Mar 26, 2008 39
Ch 20 Mapping Designs to Code
With the completion of interaction diagrams and DCDs for the current iteration of the case studies, there's more than enough thought and detail to cut some code for the domain layer of objects.
The UML artifacts created during the design work - the interaction diagrams and DCDs - will be used as input to the code generation process.
In UP terms, there exists an Implementation Model. – This is all the implementation artifacts, such as the source code,
database definitions, JSP/XML/HTML pages, and so forth. Thus, the code being created in this chapter can be considered part of the UP Implementation Model.
Mar 26, 2008 40
Programming and Iterative, Evolutionary Development
The prior design modeling should not be taken to imply that there is no prototyping or design-while-programming; modern development tools provide an excellent environment to quickly explore and refactor alternate approaches, and some (often lots) design-while-programming is worthwhile.
The creation of code in an OO language - such as Java or C# - is not part of OOA/D, it's an end goal.
The artifacts created in the Design Model provide some of the information necessary to generate the code.
Mar 26, 2008 41
Creativity and Change During Implementation Some decision-making and creative work was accomplished
during design work. It will be seen during the following discussion that the generation of the code in these examples a relatively mechanical translation process.
However, in general, the programming work is not a trivial code generation step - quite the opposite!
Realistically, the results generated during design modeling are an incomplete first step; during programming and testing, myriad changes will be made and detailed problems will be uncovered and resolved
Expect and plan for lots of change and deviation from the design during programming. That's a key and pragmatic attitude in iterative and evolutionary methods.
Mar 26, 2008 42
Mapping Designs to Code Implementation in an object-oriented language
requires writing source code for:– class and interface definitions– method definitions
The following sections discuss their generation in Java (as a typical case).
The discussion is more-or-less independent of using a UML tool for code generation or working from some wall sketches.
Mar 26, 2008 43
Creating Classes from DCDs
DCDs depict the class or interface name, superclasses, operation signatures, and attributes of a class.
This is sufficient to create a basic class definition in an OO language.
If the DCD was drawn in a UML tool, it can generate the basic class definition from the diagrams.
Mar 26, 2008 44
Creating Classes from DCDs
public class SalesLineItem{private int quantity;
private ProductDescription description;
public SalesLineItem(ProductDescription desc, int qty) { ... }
public Money getSubtotal() { ... }
}
SalesLineItem
quantity : Integer
getSubtotal() : Money
ProductDescription
description : Textprice : MoneyitemID : ItemID
...
1
description
Mar 26, 2008 45
Creating Methods from Interaction Diagrams
The sequence of the messages in an interaction diagram translates to a series of statements in the method definitions.
The enterItem interaction diagram illustrates the Java definition of the enterItem method.
For this example, we will explore the implementation of the Register and its enterItem method.
A Java definition of the Register class is shown below.
Mar 26, 2008 46
Creating Methods from Interaction Diagrams
2: makeLineItem(desc, qty)enterItem(id, qty)
1: desc = getProductDesc(id) 2.1: create(desc, qty)
1.1: desc = get(id)
:Register :Sale
:ProductCatalog
sl: SalesLineItem
lineItems : List<SalesLineItem>
: Map<ProductDescription>
2.2: add(sl)
Mar 26, 2008 47
Creating Methods from Interaction Diagrams
ProductCatalog
...
getProductDesc(...)
Sale
isComplete : Booleantime : DateTime
becomeComplete()makeLineItem(...)makePayment(...)getTotal()
Register
...
endSale()enterItem(id: ItemID, qty : Integer)makeNewSale()makePayment(cashTendered : Money)
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) {...}}
1
1
catalog
currentSale
Mar 26, 2008 48
Creating Methods from Interaction Diagrams
2: makeLineItem(desc, qty)enterItem(id, qty)
1: desc := getProductDescription(id)
:Register :Sale
:ProductCatalog
{ ProductDescription desc = catalog.ProductDescription(id); currentSale.makeLineItem(desc, qty);}
Mar 26, 2008 49
Collection Classes in Code
SalesLineItem
quantity : Integer
getSubtotal()1..*
Sale
isComplete : Booleantime : DateTime
becomeComplete()makeLineItem()makePayment()getTtotal()
public class Sale{...
private List lineItems = new ArrayList();}
A collection class is necessary to maintain attribute visibility to all the SalesLineItems.
lineItems
Mar 26, 2008 50
Exceptions and Error Handling
Exception handling has been ignored so far in the development of a solution.
This was intentional to focus on the basic questions of responsibility assignment and object design.
However, in application development, it's wise to consider the large-scale exception handling strategies during design modeling (as they have a large-scale architectural impact), and certainly during implementation.
Mar 26, 2008 51
One final example (Sale.makeLineItem method)
{ lineItems.add( new SalesLineItem(desc, qty) );}
2: makeLineItem(desc, qty)enterItem(id, qty)
2.1: create(desc, qty)
:Register :Sale
sl: SalesLineItemlineItems :
List<SalesLineItem>
2.2: add(sl)
Mar 26, 2008 52
Order of Implementation
SalesLineItem
quantity : Integer
getSubtotal()
ProductCatalog
...
getProductDesc(...)
ProductDescription
description : Textprice : MoneyitemID : ItemID
...
Store
address : Addressname : Text
addSale(...)
Payment
amount : Money
...
1..*
1..*
Register
...
endSale()enterItem(...)makeNewSale()makePayment(...)
Sale
isComplete : Booleantime : DateTime
becomeComplete()makeLineItem(...)makePayment(...)getTotal()...
1
1
1
1
1
1
* 1
23
4
56
7
Classes need to be implemented (and ideally, fully unit tested) from least-coupled to most-coupled.
Mar 26, 2008 53
Summary As demonstrated, there is a translation process
– from UML class diagrams to class definitions, and – from interaction diagrams to method bodies.
There is still lots of room for creativity, evolution, and exploration during programming work.
The code example for the NextGen POS case study…
The main point of this listing is to show that there is a translation from design artifacts to a foundation of code.
This code defines a simple case; it is not meant to illustrate a robust, fully developed Java program with synchronization, exception handling, and so on.