Вы находитесь на странице: 1из 67

Patters

Designing Objects with Responsibilities GRASP Patterns

Sample UP Artifact Relationships for Use-Case Realization


Domain Model Sale date ... 1 1.. * Sales LineItem quantity ... the domain objects, attributes, and associations that undergo state changes Use-Case Model : System Operation: makeNewSale
: Cashier

...

domain objects

Process Sale 1. Customer arrives ... 2. Cashier makes new sale. 3. Cashier enters item identifier. 4.... make NewSale() enterItem (id, quantity)

Post-conditions: - ... system operations Operation: enterItem

system events

conceptual classes in the domain inspire the names of some software classes in the design

endSale()

makePayment (amount) Use Cases System Sequence Diagrams

Post-conditions: - A SalesLineItem sli was created -... Contracts

instance

some ideas and inspiration for the postconditions derive from the use cases

in addition to the use cases, requirements that must be satisfied by the design of the software

use-case realization : Register

Design Model : ProductCatalog

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

2
...

...

Methods Responsibilities

Deciding what methods belong where, and how the objects should interact, is most important The GRASP patterns are a learning aid to help one 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
3

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 about private encapsulated data Knowing about related objects

Knowing responsibilities of an object include


Knowing about things it can derive or calculate

Responsibilities and Methods

Responsibilities are assigned during object design

A Sale is responsible for creating SalesLineItem instances


(doing) A Sale is responsible for knowing its total (knowing) A responsibility is not the same thing as a method, but methods are implemented to fulfill responsibilities Responsibilities are implemented using methods that either act alone or collaborate with other methods and objects

Responsibilities and Methods

Example

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

Responsibilities and Interaction Diagrams

Creation of interaction diagrams needs 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

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:
Solution:

Information Expert
Assign a responsibility to the class that has the information needed to fulfill it What is a basic principle by which to assign responsibilities to 8 objects?

Problem it Solves:

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

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

10

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

the assignment of responsibilities to software

If responsibility assignment is done well

Systems tend to be easier to understand, maintain in future applications.

and

extend and there is more opportunity to reuse components

11

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 that class that has the information needed to determine the total.

12

Information Expert

Example
Sale date time 1 Contains

1.. *
Sales LineItem quantity

Described-by

Product Specification description price itemID

13

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

14

Information Expert

A partial solution

t := getTotal()

:Sale date time New method

Sale

getTotal()

Partial interaction and class diagram


15

Information Expert

Example

What information is SlaesLineItem subtotal?

needed

to

determine

the

SalesLineItem.quantity and SalesLineItem.price Now


SalesLineItem knows its quantity and it is associated

with ProductSpecification
By Information Expert, SalesLineItem should determine

subtotal
16

Information Expert

Example
lineItems [ i ] : SalesLineItem

t := getTotal(): Sale

1 *: st := getSubtotal()

Sale date time New method getTotal()

SalesLineItem quantity getSubtotal()

In terms of Interaction Diagram it means that Sale needs to send getSubtotal message to each of the SalesLineItem instance
17

Information Expert

Example cont

For knowing and answering its subtotal a SalesLineItem needs to know the product price ProductSpecification salesLineItem is expert for price of a

A message must be sent to it asking for price

18

Information Expert

Example
t := getTotal() : Sale 1 *: st := getSubtotal()

Sale date time getTotal()

lineItems [ i] : SalesLineItem

1.1: p := getPrice()

SalesLineItem quantity

Conclusion

To fulfill the responsibility of knowing and answering the sale's total, three responsibilities were assigned to three design classes of objects

:Product Specification

getSubtotal() Product Specification description price 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
19

Information Expert

Benefits

Information Encapsulation is maintained

As objects use their own information to fulfill tasks More robust and maintainable systems Behavior is distributed across classes that have the information

Low coupling is promoted

High cohesion is promoted

Related Patterns (to be discussed)


Low Coupling High Cohesion


20

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

21

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
22

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
23

Creator

Example

In

the

POS

application,
creating

who
a

should

be

responsible instance?

for

SalesLineItem

By Creator,

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

24

Creator

Example

Consider partial domain Model

Sale date time 1 Contains 1.. * Sales LineItem quantity Product Specification description price itemID

Described-by1

25

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.

26

Creator

Example
: Register : Sale

makeLineItem(quantity) create(quantity)

lineItems: List<SalesLineItem>

This assignment of responsibilities requires that a makeLineItem method be defined in Sale


27

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

28

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 dependant on too many other elements

Elements include classes , subsystems, systems etc.

29

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

30

Low coupling

Problem

How to support low dependency, low change impact and increased reuse?

Solution

Assign responsibilities so that coupling remains low

31

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?


32

Low coupling

Example

Register records a payment in real world domain


Creator payment pattern suggests Register for creating

The

register

instance

could

then

send

an

addPayment message to Sale , passing along the new Payment as parameter.

Interaction diagram reflecting this would be

33

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
34

Low coupling

An alternative solution

makePayment()

: Register

1: makePayment()

:Sale

1.1. create()

:Payment

35

Low coupling

Example

Which design based on assignment of responsibilities supports low coupling? Sales must be coupled with payment 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, solutions where two patterns suggests different

36

Low Coupling

Benefits

Not affected by changes in other components Simple to understand in isolation Convenient to reuse

37

Low Coupling

In Practice the level of coupling alone cant be Considered in isolation from other principles Such as Expert and high cohesion. Nevertheless It is one factor to consider in improving a design

38

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
39

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

40

High Cohesion

Problem

How to keep complexity manageable?

Solution

Assign a responsibility so that cohesion remains high

41

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
42

High Cohesion

Example

Register Creates Payment

makePayment()

: Register

1: create()

p : Payment

2: addPayment(p)

:Sale
43

High Cohesion
Example
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

44

High Cohesion

Example

Sale Creates Payment


: Register : Sale

makePayment() makePayment() create() : Payment

Since the second design supports both high cohesion and low coupling, it is preferable
45

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

46

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

47

High 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 Databases and for Remote Procedure Calls. with Relational

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

48

High 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
49

High 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

50

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

51

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

52

Controller Pattern

53

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

54

Controller

What is Controller?
A Controller is a non user interface object responsible for receiving or handling a system event

55

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

56

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
57

Controller
presses button : Cashier actionPerformed( actionEvent )
Interface Layer

:SaleJFrame
enterItem(itemID, qty) System event message

Domain Layer

: ???

Which class of object should be responsible for system event receiving this 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 58 from the interface layer.

Controller

Example

By Controller choices for controller are 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, POS System --- ProcessSaleHandler --- ProcessSaleSession


59

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

60

Controller

Normally, a controller should delegate to other objects the work that needs to be done; it coordinates or controls the activity. It does not do much work itself. Faade controller

Represents the overall system, device or subsystem. The idea is to choose some class name that

Suggests a cover or faade (front wall) over the other layers of the application and That provides the main point of service calls from the UI (User Interface) layer down to other layers.

61

Controller

Faade controllers are suitable when there are not too many system events Use case Controller

Choose a use case controller when Faade controller is becoming bloated with excessive responsibilities Different controller for each use case e.g. ProcessSaleHandler, HandleReturnsHandler It is not a domain object, rather an artificial construct to support the system

62

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

Allocation of System Operations


Register

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

system operations discovered during system behavior analysis

allocation of system operations during design, using one facade controller

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

ProcessSale Handler ...

HandleReturns Handler

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

enterReturnItem() makeNewReturn() . . .

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

63

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

64

Controller

Issues
Poorly designed a controller class will have low cohesion -unfocused and handling too many areas of responsibility; called Bloated Controller. 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.

65

Controller

Solutions to Bloated Controller

Add more controllers instead of faade, 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.

66

Controller

Related Patterns

Command Faade Layers

Separating domain logic from presentation layer Use case controller

Pure Fabrication

67

Вам также может понравиться