grasp: designing objects with responsibilities chapter 17 applying uml and patterns -craig larman
TRANSCRIPT
Agenda
Introduction to object design GRASP:
• Information Expert
• Creator
• Low Coupling
• High Cohesion
• Controller
Introduction to Object Design Inputs : use case text : objects are designed to realise the use casesSystem sequence diagrams : identify the system operation messagesOperation contracts : complement the use case. Supplementary Specification : non functional requirements GlossaryDomain Model : help name and attributes of software object.
Object DesignOutputs :
• UML interaction diagram
• Class diagram
• Package diagrams
• UI sketches and prototypes;
• database models.
Remember : not all of the input artifacts are necessary.
Fig. 17.1 UP artifacts influencing OO design
Operation: enterItem(…)
Post-conditions:- . . .
Operation Contracts
Sale
date. . .
SalesLineItem
quantity
1..*1 . . .
. . .
Domain Model
Use-Case Model
Design Model: Register
enterItem(itemID, quantity)
: ProductCatalog
d = getProductDescription(itemID)
addLineItem( d, quantity )
: Sale
Require-ments
Business Modeling
Design
Sample UP Artifact Relationships
: System
enterItem(id, quantity)
Use Case Text
System Sequence Diagrams
makeNewSale()
system events
Cashier
Process Sale
: Cashier
use case
names
system operations
Use Case Diagram
SupplementarySpecification
Glossary
starting events to design for, and detailed post-condition to satisfy
Process Sale
1. Customer arrives ...2. ...3. Cashier enters item identifier.
inspiration for names of some software domain objects
functional requirements that must be realized by the objects
ideas for the post-conditions
Register
...
makeNewSale()enterItem(...)...
ProductCatalog
...
getProductDescription(...)...
1*
non-functional requirements
domain rules
item details, formats, validation
:Bookd := getDueDate()
getDueDate message impliesBook has responsibility forknowing its due date.
Design of behavior implies assigning responsibilities to software classes.
Responsibilities: contract or obligation of a classifier”
Responsibility-Driven Design (RDD)
What’s responsibility
Doing:• Doing something itself, such as creating an object
or doing a calculation
• Initiating action in other objects
• Controlling and coordinating activities in other objects.
Knowing:• Knowing about private encapsulated data
• Knowing about related objects
• Knowing about things it can derive or calculate
Fig. 17.2 Responsibilities and methods
: Sale
makePayment(cashTendered)
: Paymentcreate(cashTendered)
abstract, implies Sale objects have a responsibility to create Payments
Responsibility Assignment is the Key
Appropriate assignment of responsibilities to classes is the key to successful design.
There are fundamental principles in assigning responsibilities that experienced designers apply.
These principles are summarized in the GRASP patterns.
GRASP: nine basic OO design principles. memorization and application of these patterns are critical for successful object-oriented designs.
1. Creator..2. Information Expert.3. Controller.4. Low Coupling.5. High Cohesion.6. Polymorphism.7. Pure Fabrication.8. Indirection.9. Don’t Talk to Strangers.
Memorizing and applying these nine principles during every design exercise is the primary course objective.
General Responsibility Assignment Software Patterns
11
GRASP Patterns
Which class, in the general case is responsible? You want to assign a responsibility to a class You want to avoid or minimize additional
dependencies You want to maximise cohesion and minimise
coupling You want to increase reuse and decrease
maintenance You want to maximise understandability …..etc.
CreatorWho should create an instance of a
particular class?Consider assigning Class B the responsibility to create an instance of class A if one of the following is true:
• B contains A.
• B aggregates A.
• B records A.
• B closely uses A.
Fig. 17.5 Applying Creator in a static model
Board has a composite aggregation association with Square.
Fig. 17.12 Partial POS domain model
Sale
time
SalesLineItem
quantity
ProductDescription
descriptionpriceitemID
Described-by*
Contains
1..*
1
1
Fig. 17.13 Creating a SalesLineItem
: Register : Sale
makeLineItem(quantity)
: SalesLineItemcreate(quantity)
Sale objects are given a responsibility to create Payments. The responsibility is invoked with a makePayment message
Information Expert
What is a basic principle by which to assign responsibilities to objects?
Assign a responsibility to the information expert —
the class with the information necessary to fulfill
the responsibility.
Applying Expert in POS Application Start assigning responsibilities by clearly
stating the responsibility.Who should be responsible for knowing the
grand total of a sale?
Where do we look for the classes that have the information needed?• First, in the Design Model.
• If no relevant classes there, look in the Domain Model, and add a corresponding software class to the Design Model.
Fig. 17.14 Associations of Sale in Domain Model
Sale
time
SalesLineItem
quantity
ProductDescription
descriptionpriceitemID
Described-by*
Contains
1..*
1
1
Fig. 17.15 Partial interaction and class diagrams
Sale
time...
getTotal()
:Salet = getTotal
New method
Adding a Sale class to the Design Model supports low representational gap.
Express responsibility of knowing the total of a sale with the method named getTotal.
What information do we need to know to determine the line item subtotal?
Fig. 17.16 SalesLineItem is Expert for Subtotal
Sale
time...
getTotal()
SalesLineItem
quantity
getSubtotal()New method
1 *: st = getSubtotal: Salet = getTotal lineItems[ i ] : SalesLineItem
this notation will imply we are iterating over all elements of a collection
How does the SalesLineItem find out the product price?
• “Partial” information experts collaborate to fulfill the responsibility.
Fig. 17.17 ProductDescription is Expert for Price
Sale
time...
getTotal()
SalesLineItem
quantity
getSubtotal()
ProductDescription
descriptionpriceitemID
getPrice()New method
:ProductDescription
1.1: p := getPrice()
1 *: st = getSubtotal: Salet = getTotal lineItems[ i ] :SalesLineItem
Example : Fig 17.3 In Monopoly, which class should be responsible for knowing a Square, given a key (e.g., its name)?
27
Example : Fig 17.4 - 17.5In Monopoly, which class should be responsible for knowing a Square, given a key (e.g., its name)?
28
29
:Library
borrowResource(callNum)
1: r := getResource(callNum): Resource:Catalog
Catalog is an information expert onfinding and returning a resource,based on a call number. It logicallycontains all of them.
by Expert
What class should be responsible forknowing a resource, given a call number?
Another Example
The Low Coupling Principle Problem : Reduce the impact of change. Solution: Assign responsibilities so that coupling
remains low.• Use this principle to evaluate alternatives.
Coupling: how strongly one element is connected to, has knowledge of, or relies on other elements.• Low coupling tends to reduce the time, effort, and defects
in modifying software.
• Coupling per se is not a problem, only coupling to elements that are unstable (likely to change).
Low Coupling in POS Case Study
What class should be responsible for creating a Payment instance and associating it with the Sale?• Register?
• Sale?
Creator pattern suggests Register should create the Payment.• A register records a payment in the real world.
Fig. 17.18 Register creates Payment
: Register p : Payment
:Sale
makePayment() 1: create()
2: addPayment(p)
Register is coupled to both Sale and Payment.
Fig. 17.19 Sale creates Payment
: Register :Sale
:Payment
makePayment() 1: makePayment()
1.1. create()
Assuming that the Sale must eventually be coupled to knowledge of a Payment, having Sale create the Payment does not increase coupling.• Low Coupling and Creator suggest different solutions.
Common Forms of Coupling in OO Languages
Type X has an attribute (data member, instance variable) that refers to type Y or an instance of Y.
An object of type X calls on services of a type Y object.
Type X has a method that references an instance of type Y (e.g., parameter, local variable, object returned from a method).
Type X is a subclass of type Y. Type X implements the interface Y.
Fig. 17.8 System Sequence Diagram for Monopoly
Actors generates UI events by clicking on a buttons. UI software objects(Jframe window and Jbutton button) reacts to the mouse click and cause the game to play. UI objects pick up the mouse events and should delegate the request to domain objects in the domain layer.
Controller Pattern
What first object beyond the UI layer receives and coordinates (“controls”) a system operation message?
Solution: Assign the responsibility to a class that represents one of the following options:
Options for Control Responsibility
Option 1a: Represents the overall system or a root object.• E.g., an object called MonopolyGame.
Option 1b: Represents the device the software is running within.
• E.g., Phone or BankCashMachine.• Not applicable in the Monopoly case.
Option 2: Represents the use case or session.
• E.g., PlayMonopolyGameHandler.
Fig. 17.10 Using MonopolyGame as Controller
Option 1 is reasonable if there are only a few system operations.
Fig. 17.20 System Operations of POS Application
System
endSale()enterItem()makeNewSale()makePayment(). . .
During analysis, system operations may be assigned to a System class.• Does not mean a software class
named System fulfills the system operations during design.
• During design, a controller class is assigned the responsibility for system operations.
Fig. 17.21 What should be Controller for enterItem?
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.
actionPerformed( actionEvent )
: ???
: Cashier
:SaleJFrame
presses button
enterItem(itemID, qty)
UI Layer
Domain Layer
system operation message
Fig. 17.22 Controller choices ?
:RegisterenterItem(id, quantity)
:ProcessSaleHandlerenterItem(id, quantity)
In the POS domain, Register (POS Terminal) is a specialized device with software running on it.
ProcessSaleHandler represents a receiver of all system events of a use case scenario.
Fig. 17.23 Allocation of system operations
Register
...
endSale()enterItem()makeNewSale()makePayment()
makeNewReturn()enterReturnItem(). . .
System
endSale()enterItem()makeNewSale()makePayment()
makeNewReturn()enterReturnItem(). . .
system operations discovered during system behavior analysis
allocation of system operations during design, using one facade controller
ProcessSaleHandler
...
endSale()enterItem()makeNewSale()makePayment()
System
endSale()enterItem()makeNewSale()makePayment()
enterReturnItem()makeNewReturn(). . .
allocation of system operations during design, using several use case controllers
HandleReturnsHandler
...
enterReturnItem()makeNewReturn(). . .
During design, system operations identified during system behaviour analysis are assigned to one or more controller classes.
Delegation
UI layer objects delegate system events to another layer.• UI layer shouldn’t contain application logic.
• Increases potential for reuse.
• Can “unplug” UI layer – use a different framework or run in offline “batch” mode.
Controller should delegate the work that needs to be done to other objects.• It controls or coordinates the activity.
Fig. 17.24 Desirable coupling of UI and domain layers
actionPerformed( actionEvent )
:Register
: Cashier
:SaleJFrame
presses button
1: enterItem(itemID, qty)
:Sale1.1: makeLineItem(itemID, qty)
UI Layer
Domain Layer
system operation message
controller
Fig. 17.25 Undesirable coupling of UI to domain layer
Cashier
:SaleJFrame
actionPerformed( actionEvent )
:Sale1: makeLineItem(itemID, qty)
UI Layer
Domain Layer
It is undesirable for an interfacelayer 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.
SaleJFrame should not send this message.
presses button
Façade Controller Façade controller represents the overall
system, device, or subsystem.• A façade or cover over other layers.
• Abstraction of overall physical unite.g., Register, TelecommSwitch, Robot, or
class representing entire system or concepte.g., POSSystem, ChessGame.
Suitable when there are not too many system events or when UI cannot choose between multiple controllers.
Use Case Controller A use case controller handles system
events for a single use case.• Can maintain information about the state of the
use case.• E.g., detect out-of-sequence system events.
• Different controller for each use case.
Not a domain object, but artificial construct (“pure fabrication”) to support the system.
Use when there are many system events.• Factors handling into separate classes.
:LibraryborrowResource(callNum)
by Controller
Controller - Facades Facades are “covers.” Intent - A class that (in some way) represents an overall
cover. Many possibilities.
• Example: The entire organization.
:LibSystemborrowResource(callNum)
:LibInfoSystemborrowResource(callNum)
Controller - FacadesOther facades? A class representing the “system.” Examples: The software information system. The device that includes a computer and software such as an ATM. Others.
Controller
:LibrarianborrowResource(callNum)
:BorrowResourceHandler
borrowResource(callNum)
role controller
use case controller
High Cohesion Solution
• Assign a responsibility so that cohesion remains high Problem
• How to keep complexity manageable? Cohesion is a measure of how strongly related
and focused the responsibilities of an element (classes, subsystems) are
A class with low cohesion does many unrelated things, or does too much work
They suffer from the following problems:
• hard to understand
• hard to reuse
• hard to maintain
• delicate; constantly effected by change
Benefits of High Cohesion
Clarity and ease of comprehension of the design is increased.
Maintenance and enhancements are simplified.
Low coupling is often supported.
The fine grain of highly related functionality supports increased reuse because a cohesive class can be used for a very specific purpose.
Fig. 17.26 Reduced cohesion of Register(creator pattern)
: Register : Sale
addPayment( p )
p : Paymentcreate()makePayment()
Low cohesion:
Register is taking part of the responsibility for fulfilling “makePayment” operation and many other unrelated responsibility ( 50 system operations all received by Register).then it will become burden with tasks and become incohesive