grasp: designing objects with responsibilities chapter 17 applying uml and patterns -craig larman

61
GRASP: Designing Objects With Responsibilities Chapter 17 Applying UML and Patterns -Craig Larman

Upload: bryan-small

Post on 31-Dec-2015

298 views

Category:

Documents


2 download

TRANSCRIPT

GRASP: Designing Objects With Responsibilities

Chapter 17

Applying UML and Patterns

-Craig Larman

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.

Creator

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.3 Monopoly iteration-1 domain model

Fig. 17.4 Applying the Creator pattern (dynamic model)

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

Creating a Book

:Catalog

makeBook(title)

1: create(title):Book

by Creator

Information Expert

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

Low Coupling Principle

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).

32

Fig. 17.7 Don’t assign getSquare to an arbitrary class

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.

Controller Pattern

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.

Who is Controller for playGame or How to connect the UI layer to the application logic?

Fig. 17.10 Using MonopolyGame as Controller

Option 1 is reasonable if there are only a few system operations.

44

Remind from analysis: System Operations of POS Application

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

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

Fig. 17.27 Higher Cohesion and Lower Coupling

: Register : Sale

makePayment()

: Paymentcreate()

makePayment()

Solution:

Delegate the payment creation responsibility to “Sale” to support high cohesion