You are on page 1of 70

Software Construction

LECTURE 12
DESIGNING OBJECTS WITH RESPONSIBILITIES
GRASP PATTERNS

1
Sample UP Artifact Relationships for Use-Case Realization
Domain Model

Sale 1 1.. * Sales


...
LineItem
date
...
... quantity

the domain objects, attributes, and


domain objects associations that undergo state changes
Use-Case Model

: System
Process Sale Operation: makeNewSale
: Cashier make
1. Customer NewSale() Post-conditions:
arrives ... - ...
2. Cashier system system
makes new enterItem
events operations
sale. (id, quantity)
conceptual 3. Cashier Operation: enterItem
classes in enters item
the identifier. endSale()
Post-conditions:
domain 4.... - A SalesLineItem instance
inspire the sli was created
names of makePayment -...
some (amount)
software
classes in Use Cases System Sequence Diagrams Contracts
the design in addition to the use
cases, requirements that
some ideas and inspiration for the post- must be satisfied by the
conditions derive from the use cases design of the software

use-case Design Model


realization
: Register : ProductCatalog

makeNewSale()
create()
: Sale
enterItem
(itemID, quantity)
spec := getSpecification( itemID )
addLineItem( spec, quantity )
...

endSale()
... ...
2
Responsibilities
Deciding what methods belong where, and how the objects should interact, is
most important
The GRASP patterns are a learning aid in understanding essential object design
GRASP stands for General Responsibility Assignment Software Patterns
UML defines Responsibility as
◦ “a contract or obligation of a class”

Responsibilities are related to the obligations of an object in terms of its


behavior
Responsibilities are of two types
◦ Doing
◦ Knowing

7
Responsibilities and Methods
Doing responsibilities of an object include
◦ 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 responsibilities of an object include


◦ knowing about private encapsulated data
◦ Knowing about related objects
◦ Knowing about things it can derive or calculate

8
Responsibilities and Methods
Examples of Responsibilities
◦ A Sale is responsible for creating SalesLineItem instances (doing)
◦ A Sale is responsible for knowing its total (knowing)

Responsibilities are assigned during object design

Responsibility is not the same thing as a method


◦ methods are implemented to fulfill responsibilities

Responsibilities are implemented using methods that either act alone or


collaborate with other methods and objects

9
Responsibilities and Methods
Example: Collaborating with other objects
◦ The class Sale might define one or more methods to know its total
(say a getTotal method). To fulfill that responsibility, the Sale may
collaborate with other objects e.g. sending a getSubTotal message to
each SalesLineItem object

10
Responsibilities and Interaction
Diagrams
Creation of interaction diagrams need fundamental principles (called
Patterns) for assigning responsibilities to objects
: Sale

makePayment(cashTendered)
create(cashTendered)
: Payment

implies Sale objects have a


responsibility to create Payments

Interaction diagrams show choices in assigning responsibilities


to objects
11
Patterns
A Pattern is a named description of a problem and solution that can be
applied to assign responsibilities
Patterns provide guidance for how responsibilities should be assigned to
objects

Pattern Name: Information Expert


Solution: Assign a responsibility to the class that has the
information needed to fulfill it
Problem it Solves: What is a basic principle by which to assign
responsibilities to objects?

12
GRASP Patterns
First five GRASP patterns
◦ Information Expert
◦ Creator
◦ High Cohesion
◦ Low coupling
◦ Controller

There are other patterns as well, but these address very basic, common
questions and fundamental design issues

13
Information Expert
Problem
◦ What is a general principle of assigning responsibilities to objects?

Solution
◦ Assign a responsibility to the information Expert – the class that has
the information necessary to fulfill the responsibility

14
Information Expert
Problem Explanation
◦ A design model may define hundreds of software classes and an
application may require hundreds of responsibilities to be fulfilled
◦ When the interactions between objects are defined, we make
choices about the assignment of responsibilities to software classes
◦ If responsibility assignment is done well
◦ Systems tend to be easier to understand, maintain and extend and there
is more opportunity to reuse components in future applications

15
Information Expert - example
In the NextGenPOS application, some class needs to know the grand total
of a sale

Start assigning responsibilities by clearly stating the responsibility


◦ Who should be responsible for knowing the grand total of a
Sale?

By Information Expert we should look for the class that has the
information needed to determine the total

16
Information Expert - Example cont…

Sale

date
time

1
Contains

1.. *
Product
Sales Specification
LineItem * Described-by
1
description
quantity price
itemID

17
Information Expert
Example
◦ What Information is needed to determine the grand total?
◦ It is necessary to know about all the SalesLineItem instances of a sale and the
sum of their subtotal
◦ Sale class contains this information, therefore suitable for this responsibility
i.e. getTotal
◦ It is an Information Expert for this work

18
Information Expert
A partial solution

t := getTotal() Sale
:Sale
date
t ime

New method getTotal()

Partial interaction and class diagram


19
Information Expert – Example cont…
What information is needed to determine the SlaesLineItem subtotal?

 SalesLineItem.quantity and SalesLineItem.price


 Now
 SalesLineItem knows its quantity and it is associated with
ProductSpecification
 By Information Expert, SalesLineItem should determine
subtotal

20
Information Expert – Example cont…

t := getTotal() 1 *: st := getSubtotal() lineItems [i] :


: Sale SalesLineItem

Sale SalesLineItem
date quantity
time
New method getSubtotal()
getTotal()

• In terms of Interaction Diagram it means that Sale needs to send


getSubtotal message to each of the SalesLineItem instance

21
Information Expert - Example cont…
For knowing and answering its subtotal a SalesLineItem needs to
know the product price

ProductSpecification is expert for price of a salesLineItem

A message must be sent to it asking for price

22
Information Expert Sale

date
time
t := getTotal() 1 *: st := getSubtotal() lineItems[i] :
: Sale getTotal()
SalesLineItem

1.1: p := SalesLineItem
Conclusion getPrice() quantity
To fulfill the responsibility of :Product getSubtotal()
knowing and answering Specification

the sale's total, three Product


Specification
responsibilities were
description
assigned to three design price
classes of objects itemID
New method getPrice()

• The principle by which each responsibility was assigned was Information


Expert- placing it with the object that has the information needed to
fulfill it
23
Information Expert - Benefits
Information Encapsulation is maintained
◦ As objects use their own information to fulfill tasks

Low coupling is promoted


◦ More robust and maintainable systems

High cohesion is promoted


◦ Behavior is distributed across classes that have the information

Related Patterns (to be discussed)


◦ Low Coupling

◦ High Cohesion

24
Creator
Problem
◦ Who should be responsible for creating a new instance of some class?

◦ Creation of objects is most common activity

◦ It is useful to have a general principle for assignment of creation


responsibilities
◦ Assigned well, the design can support low coupling, increased clarity,
encapsulation and reusability

25
Creator
Solution
◦ Assign class B the responsibility to create an instance of class A if one or more of the
following conditions is true
◦ B contains or compositely aggregates A objects.
◦ B records instances of A objects.
◦ B closely uses A objects.
◦ B has initializing data that will be passed to A when it is created

B is creator of A objects.
If more than one options, prefer a class B which compositely aggregates or contains class A

26
Creator
Sometimes a creator is found by looking for the class that has the initializing

data that will be passed in during instance creation

◦ Initializing data is passed in during creation via some kind of initialization

method, such as a Java or C++ constructor that has parameters

◦ Example

◦ a Payment instance needs to be initialized, when created with the Sale

total

◦ Since Sale knows the total, Sale is a candidate creator of the payment

27
Creator – Example cont…
In the POS application, who should be responsible for creating a
SalesLineItem instance?

By Creator,
◦ We should look for a class that aggregates, contains and so on,
SalesLineItem instances

28
Creator
Consider partial domain Model

Sale

date
time

1
Contains

1.. *
Product
Sales Specification
LineItem * Described-by 1
description
quantity price
itemID

29
Creator
Example
◦ Since Sale contains many SalesLineItem Objects

◦ Creator pattern suggests that Sale is a good candidate to have the


responsibility of creating SalesLineItem instances.

30
Creator
: Register : Sale

makeLineItem(quantity)
create(quantity) lineItems:
List<SalesLineItem>

This assignment of responsibilities requires that a makeLineItem


method be defined in Sale
31
Creator - Benefits
Low Coupling is supported
◦ Which implies lower maintenance dependencies, and higher
opportunities of reuse
◦ Coupling is not increased because the created class is already
visible to creator class due to existing association

Related Patterns
◦ Low coupling
◦ Factory

32
Who creates the Squares?
Coupling
Coupling is a measure of how strongly one element is connected to,
has knowledge of, or relies on other elements.

An element with low or weak coupling is not dependent on too many


other elements

Elements include classes, subsystems, systems etc.

35
Coupling
A class with high or strong coupling relies on many other classes

Some classes may be undesirable; and suffer from following problems


◦ Changes in related classes force local changes

◦ Harder to understand in isolation

◦ Harder to reuse because its use requires the additional presence of the
classes on which it is dependent.

36
Low Coupling
Problem
◦ How to support low dependency, low change impact and increased
reuse?

Solution
◦ Assign responsibilities so that coupling remains low

37
Low Coupling - Example
Consider the following partial diagram

Payment Register Sale

 Assume we have a need to create a payment instance


and associate with the sale
 What class should be responsible for this?

38
Low Coupling-Example cont…
Register records a payment in real world domain

Creator pattern suggests Register for creating payment

The Register instance could then send an addPayment message to


Sale, passing along the new Payment as parameter.

Interaction diagram reflecting this would be…

39
Low Coupling

makePayment() : Register 1: create() p : Payment

2: addPayment(p)
:Sale

Note that Payment instance is explicitly named ‘p’ so


that in message2 it can be referenced as parameter

40
Low Coupling
An alternative solution

makePayment() : Register 1: makePayment() :Sale

1.1. create()

:Payment

41
Low Coupling – Example cont…
Which design based on assignment of responsibilities supports low coupling?

Sales must be coupled with payment

In Diagram1, in which the Register creates the payment, adds coupling of payment

In Diagram2 Sale does the creation of payment and it does not increase coupling

From the point of view of Coupling Design2 is preferable

An example, where two patterns suggests different solutions

42
Low Coupling - Benefits
Not affected by changes in other components

Simple to understand in isolation

Convenient to reuse

43
Low Coupling

In Practice the level of coupling alone can’t be


Considered in isolation from other principles
Such as Information Expert and high cohesion.
Nevertheless It is one factor to consider
in improving a design

44
Cohesion
Cohesion is a measure of how strongly related and focused the
responsibilities of an element are.

An element with highly related responsibilities and which does not do a


tremendous amount of work, has high cohesion.

A class with low cohesion does many unrelated things, or does too
much work.

Such classes are undesirable; they suffer from many problems

45
Cohesion
Low Cohesion classes suffer from problems like;
◦ Hard to comprehend (understand)

◦ Hard to reuse

◦ Hard to maintain

◦ Delicate; constantly affected by change

Low cohesion classes often have taken on responsibilities that should


have been delegated to other classes

46
High Cohesion
Problem
◦ How to keep complexity manageable?

Solution
◦ Assign a responsibility so that cohesion remains high

47
High Cohesion
Example (same example problem used in Low Coupling pattern can be
analyzed for High Cohesion)
◦ We have a need to create a Payment instance and associate it with Sale.
◦ Which class should be responsible for it?
◦ As discussed earlier, in real world domain Register records Payment
◦ Creator Pattern suggests Register as a candidate class for creating a
Payment instance
◦ Register instance could then send an addPayment message to the Sale
passing new Payment instance as a parameter

48
High Cohesion - Example
Register Creates Payment

makePayment() : Register 1: create() p : Payment

2: addPayment(p)
:Sale

49
High Cohesion
Register Creates Payment

This single system event does not make Register class incohesive

But there exists many related system events (e.g. fifty system operations/events)

If Register is assigned responsibility for all these system operations; it may


become incohesive object

• Second design ( next example ) supports high cohesion and low coupling

50
High Cohesion
Sale Creates Payment
: Register : Sale

makePayment()
makePayment()
create()
: Payment

Since the second design supports both high cohesion and low coupling, it
is preferable
51
High Cohesion

In Practice, the level of cohesion alone can


not be considered in isolation from other
responsibilities and other principles such
as Information Expert and Low Coupling

52
High Cohesion
Functional Cohesion
◦ When the elements of a component (a class) “all work together to provide
some well-bounded behavior” [Grady Booch 94]

Scenarios that illustrate varying degrees of functional cohesion


◦ Very Low Cohesion

◦ Low Cohesion

◦ High Cohesion

◦ Moderate Cohesion

53
Functional Cohesion
Very Low Cohesion
◦ A class is solely responsible for many things in different functional areas

◦ Example
◦ Assume a class RDB-RPC-Interface

◦ That is completely responsible for interacting with Relational Databases and for Remote
Procedure Calls.

◦ These two are vastly different areas and each requires lots of supporting code

◦ Therefore, the responsibilities should be split into a family of classes related to RDB
access and a family related to RPC support

54
Functional Cohesion
Low Cohesion
◦ A class has sole responsibility for a complex task in one functional area

◦ Example
◦ Assume A class RDBInterface

◦ That is completely responsible for interacting with Relational Database

◦ The methods of the class are all related, but there are lots of them, and there is a
tremendous amount of supporting code;
◦ There may be hundreds of methods

◦ The class should be split into a family of light-weight classes sharing the work to provide
RDB access

55
Functional Cohesion
High Cohesion
◦ A class has moderate (reasonable) responsibilities in one functional
area and collaborates with other classes to fulfill tasks
◦ Example
◦ Assume A class RDBInterface having partial responsibility for interacting with RDB
◦ It interacts with a dozen (may be) other classes related to RDB access in order to retrieve
and save objects

56
High Cohesion
Moderate Cohesion
◦ A class has lightweight and sole responsibilities in a few different areas
that are logically related to the class concept, but not to each other.
◦ Example
◦ Assume A class Company that is completely responsible for
◦ knowing its employees information and
◦ Knowing its financial information

◦ These two areas are not strongly related to each other although these two are logically
related to the concept of Company

57
High Cohesion - Benefits
Clarity and ease of comprehension (understanding) of the design

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

58
Controller Pattern

59
Controller
It is related with handling an input system event?
◦ An input system event is an event generated by an external actor

They are associated with system operations


◦ Operations of the system in response to system events, just as messages and
methods are related
◦ When a Cashier (in POS) presses “endSale” button, he is generating a system event
indicating “the sale has ended”
◦ When a person presses the “SpellCheck” button (in a Word Processor), and
generating the event, indicating “perform a spell check”

60
Controller
What is Controller?

A Controller is a non user interface object responsible for receiving or


handling a system event

61
Controller
Problem
◦ Who should be responsible for handling an input system event?

Solution
◦ Assign the responsibility for receiving or handling a system event
message to a class representing one of the following choices
◦ Class that represents the overall system, device or subsystem
◦ Class that represents a use case scenario within which the system event occurs,
often named as;
◦ <UseCaseName>Handler
◦ <UseCaseName>Coordinator
◦ <UseCaseName>Session

62
Controller - Example
In NextGenPOS there are different system operations

System

endSale()
enterItem()
makeNewSale()
makePayment()
...

Who should be responsible for system events like


enterItem and endSale
63
Controller

presses button

: Cashier

actionPerformed( actionEvent )

Interface
Layer :SaleJFrame
System event message
enterItem(itemID, qty)

Which class of objects should be responsible for


Domain receiving thissystem event message?
Layer : ???
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.
64
Controller
The choices for controller
◦ The class that represents overall system, device or subsystem

The class that represents a receiver or handler of all system events of a use
case scenario

--- Register, POSSystem


--- ProcessSaleHandler
--- ProcessSaleSession

65
Controller

In terms of Interaction Diagrams, it means that one of the examples in


following figure may be useful

enterItem(id, quantity)
:Register

enterItem(id, quantity)
:ProcessSaleHandler

66
Controller
Normally, a controller delegates the work to other objects
◦ It coordinates or controls the activity & does not do much work itself

Façade controller
◦ Represents the overall system, device or subsystem

◦ The idea is to choose some class that


◦ Suggests a cover or façade (front wall) over the other layers of the application

◦ That provides the main point of service calls from the UI (User Interface) layer down
to other layers

67
Controller
Façade controllers are suitable when there are not too many system
events

Use case Controller


◦ Choose a use case controller when Façade controller is becoming “bloated”
with excessive responsibilities
◦ May have a different controller for each use case
◦ e.g. ProcessSaleHandler, HandleReturnsHandler

◦ It is not a domain object, rather an artificial construct to support the system

68
Allocation of System Operations
System Register

endSale() ...
enterItem()
makeNewSale() endSale()
makePayment() enterItem()
makeNewSale()
makeNewReturn() makePayment()
enterReturnItem()
... makeNewReturn()
enterReturnItem()
...

system operations allocation of system


discovered during system operations during design,
behavior analysis using one facade controller

ProcessSale HandleReturns
System Handler Handler

endSale() ... ...


enterItem()
makeNewSale() endSale() enterReturnItem()
makePayment() enterItem() makeNewReturn()
makeNewSale() ...
enterReturnItem() makePayment()
makeNewReturn()
...

allocation of system
operations during design,
using several use case
controllers

69
Controller - Benefits
Increased potential for reuse and pluggable interfaces
◦ It ensures that Application logic is not handled in interface layer

◦ Application logic is not bound to interface layer

Reasoning about the state of use case


◦ To ensure that system operations occur in legal sequence
◦ E.g. makePayment operation cannot occur before endSale operation

70
Controller - Issues
Poorly designed a controller class will have low cohesion

Bloated Controller
◦ Unfocused and handling too many areas of responsibility

◦ Signs are
◦ A single controller class, receiving all system events

◦ Controller class itself performs many tasks without delegating work. This usually
involves violation of Information Expert and High Cohesion

◦ A controller has many attributes and maintains significant information about domain,
which should have been distributed to other objects, or duplicates information found
elsewhere.
71
Controller
Solutions to Bloated Controller
◦ Add more controllers – instead of façade, use use-case controllers

◦ For example, in an airline reservation system; there may be many controllers


(MakeReservationHandler, ManageScheduleHadler, ManageFaresHandler) rather
than just one facade
◦ Design the controller so that it primarily delegates the fulfillment of each system
operation responsibility on to other objects.

72
Controller
Related Patterns
◦ Command

◦ Façade

◦ Layers
◦ Separating domain logic from presentation layer

◦ Pure Fabrication
◦ Use case controller

73
Patterns for Presentation
Creational patterns Structural patterns Behavioral patterns
◦ Abstract Factory ◦ Adapter ◦ Chain of Responsibility
◦ Builder ◦ Bridge ◦ Command
◦ Factory Method ◦ Composite ◦ Interpreter
◦ Prototype ◦ Decorator ◦ Iterator
◦ Singleton ◦ Proxy ◦ Observer
◦ State
◦ Strategy
◦ Visitor

74

You might also like