Chapter 17: GRASP : Designing Objects with Responsibilities - PowerPoint PPT Presentation

1 / 53
About This Presentation
Title:

Chapter 17: GRASP : Designing Objects with Responsibilities

Description:

Actors, such as the human observer in the Monopoly game, generate UI events, ... In terms of an interaction diagram, this means that the Sale should send ... – PowerPoint PPT presentation

Number of Views:366
Avg rating:3.0/5.0
Slides: 54
Provided by: christop139
Category:

less

Transcript and Presenter's Notes

Title: Chapter 17: GRASP : Designing Objects with Responsibilities


1
Chapter 17 GRASP Designing Objects with
Responsibilities
  • 17.1 Introduction
  • Since the UML is simply a standard visual
    modeling language, knowing its details doesn't
    teach you how to think in objects
  • This chapter and the next present the heart of
    OOD they explain fundamental skills in OOD and
    are therefore very important.
  • We emphasise the design of the dynamic view of
    the software solution (via the interaction
    diagrams) rather than the static view of the
    software (i.e. the design class diagram).

2
  • 17.2 Design in an Iterative Process
  • We assume that many activities have already taken
    place generating many useful artifacts prior to
    design
  • Vision
  • Supplementary Specification
  • Domain Model
  • Use Cases
  • System Sequence Diagrams
  • Operation Contracts
  • In an agile approach however, not all artifacts
    may be fully detailed while additional others may
    well be needed Common artefacts are summarised
    on Figure 17.1
  • It would be a big mistake however to start
    designing if we are having problems creating the
    artifacts above
  • in particular if your contracts are poor it is
    without doubt because you are on the wrong track
    The level of quality of the contracts is a very
    good indicator of future success for the
    iteration and therefore the project

3
(No Transcript)
4
  • During OOD, using the previously generated
    artifacts and via the UML we explore visually the
    necessary relationships between the objects to
    fulfil the requirements (we may only do so for
    the difficult parts of the design that we wish to
    explore before coding for the obvious parts,
    coding can be started as soon as what we have to
    do has been agreed (e.g. as described in a
    contract and supported by the domain model)
  • We may update previous artifacts or explore them
    further in case of problems
  • We sketch both interaction diagrams and
    complementary class diagrams (dynamic and static
    modeling) applying general OO design patterns
    (aka principles)
  • We may record our effort using a fully fledged
    UML modeling tool (but remembering that in an
    agile approach we build models primarily to
    understand and communicate not to document) this
    does not mean that documentation is not
    necessary!
  • We may intertwine coding half-days in between
    modeling half-days within a single iteration
  • We must remain agile (but honest with ourselves).

5
  • Hence what we will see now may only apply to the
    most difficult parts of the software (these tend
    to be front-loaded in an evolutionary project, so
    that more time may be spent on hard OOD in the
    first few iterations than in the subsequent ones
    were direct coding may be acceptable) but
    obviously we will apply what we learn on simple
    examples

6
  • 17.3 Responsibilities and Responsibility-Driven
    Design
  • A good way to design a solution in terms of
    collaborating objects is to think in terms of
    responsibilities
  • Responsibilities are related to the obligations
    or behaviour of an object in terms of its role
  • Objects (and therefore classes) will be assigned
    responsibilities during OOD
  • Two types of responsibilities, doing and
    knowing
  • 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

7
  • So during OOD we may decide for example that "a
    Sale is responsible for creating SalesLineItems"
    (a doing responsibility), or "a Sale is
    responsible for knowing its total" (a knowing
    responsibility)
  • Assigning some responsibilities can be obvious,
    for example if the domain model Sale class has a
    time attribute, it is obvious that a Sale object
    should be responsible for knowing its time. (no
    need for OOD to find that out )
  • On the other hand some responsibilities may
    involve hundreds of objects and rely on hundred
    of methods
  • A responsibility is not the same thing as a
    method methods fulfil responsibilities.
  • Responsibilities are implemented by means of
    methods that either act alone or collaborate with
    other methods and objects.

8
  • Responsibility Driven Design is a general
    metaphor for thinking about OO software design.
    Think of software objects as similar to people
    with responsibilities who collaborate with other
    people to get work done. Responsibility Driven
    Design leads to viewing an OO design as a
    community of collaborating responsible objects.
  • We use interaction diagram to illustrate these
    collaborations between objects.
  • Given a responsibility there are usually many
    potential solutions in terms of collaborating
    objects
  • Patterns are there to guide us towards good
    solutions

9
  • 17.4 Patterns
  • A pattern is a named and well-known
    problem/solution pair that can be applied in new
    contexts, with advice on how to apply it in novel
    situations and discussion of its trade-offs,
    implementations, variations, and so forth
  • There are hundreds of OO design patterns, only a
    few a fundamentals
  • Patterns do not express new software engineering
    ideas quite the opposite in fact. Patterns
    codifies good solutions to well-known recurring
    problems. In fact many OOD patterns originate
    from traditional non-OO software engineering
  • Patterns have names which allow easier
    communication we can talk of the low-coupling
    pattern, or the controller pattern and everyone
    knows what is being talked about.

10
  • An example of a basic pattern
  • Pattern Name Information Expert
  • Problem What is a basic principle by which to
    assign responsibilities to objects?
  • Solution Assign a responsibility to the class
    that has the information needed to fulfill it.
  • this is a very basic pattern, and one of the most
    useful (even just asking ourselves the question
    who should be responsible for doing/knowing so
    and so? yields an obvious answer).
  • A very well known design pattern book by the
    gang of four (GoF) is Design patterns
    elements of reusable object-oriented software by
    Erich Gamma, Richard Helm, Ralph Johnson, John
    Vissides. Addison Wesley, 1995, ISBN 0201633612.

11
  • 17.5 Responsibilities, Patterns, Interaction
    Diagrams and Coding
  • We need to assign responsibilities to objects
    while coding or while sketching
  • Creating interaction diagrams implies making
    decisions about responsibilities allocation we
    use patterns to guide us. E.g.

12
  • The previous figure, indicates that Sale objects
    have been given a responsibility to create
    Payments, which is concretely invoked with a
    makePayment message and handled with a
    corresponding makePayment method. Furthermore,
    the fulfillment of this responsibility requires
    collaboration to create the Payment object and
    invoke its constructor.
  • The patterns that we will use are the
  • GRASP (General Responsibility Assignment Software
    Patterns) 9 patterns (Craig Larmans)
  • Some GoF patterns

13
  • 17.6 Short Responsibility-Driven Design Example
  • We are using the monopoly case study recall the
    previous domain model
  • Lets look at a few OO patterns to help with
    responsibility assignment

14
  • One of the first problems you have to consider in
    OO design is Who creates object X? This is a
    doing responsibility. For example, in the
    Monopoly case study, who creates a Square
    software object?
  • Any object could create a square object
  • But it is obvious here that the board should be
    responsible for creating square objects
  • This kind of intuitive, experience
    based-knowledge is captured in OO Patterns, here
    the Creator pattern.
  • The creator pattern
  • Name Creator
  • Problem Who creates an A?
  • Solution Assign class B the responsibility to
    create an instance of class A if one of these is
    true
  • B "contains" or compositely aggregates A.
  • B records A.
  • B closely uses A.
  • B has the initializing data for A.

15
  • Hence we can start dynamic modeling
  • And we can start static modeling

16
  • Another kind of common problem is who knows or
    can do something? For example, who knows about a
    Square object, given a key (a knowing
    responsibility)?
  • Any object could be assigned the job
  • But there is one obvious answer the board
  • This kind of intuitive, experience
    based-knowledge is captured in OO Patterns, here
    the Information Expert pattern.
  • The information expert pattern
  • Name Information Expert
  • Problem What is a basic principle by which to
    assign responsibilities to objects?
  • Solution Assign a responsibility to the class
    that has the information needed to fulfill it.

17
  • Below are the necessary dynamic and static models
  • Hence, here by the expert pattern we have
    decided, that to retrieve squares other objects
    will go via the board object first, the board
    offers this service to others as a public method
    in other words it has been decided during design
    that it is responsible for this low-level
    service.
  • We could have decided that another object, maybe
    a new one, be given this responsibility instead,
    say a Dog class

18
  • Obviously the Expert pattern, and our common
    sense in this simple case, advise us that Board
    is the only candidate but what if another
    class, say Dog, be given the job instead? What
    would happen?
  • It would work the problem is not about
    correctness
  • It would however violate another sound, generic,
    design principle low coupling.
  • Low coupling is another design pattern it says
    that whenever we have choice we must go for the
    solution that maintain the lowest level of
    coupling in the design.
  • Informally, coupling is a measure of how strongly
    one element is connected to, has knowledge of, or
    depends on other elements. If there is coupling
    or dependency, then when the depended-upon
    element changes, the dependant may be affected.
    For example, a subclass is strongly coupled to a
    superclass. An object A that calls on the
    operations of object B has coupling to B's
    services.

19
  • The low coupling pattern
  • Name Low Coupling
  • Problem How to reduce the impact of change?
  • Solution Assign responsibilities so that
    (unnecessary) coupling remains low. Use this
    principle to evaluate alternatives.
  • E.g. consider the effect of choosing a Dog
    object the responsibility to retrieve squares

20
  • Note A Map (aka a Table) is a data structure
    that allows retrieval of entities via a key
    (which may be arbitrary)
  • Low coupling is a very important, basic, generic,
    design principle it is also an OOD pattern
  • We must also consider during design how to link
    the GUI with the logic of the application in
    business application at least a very common
    overall architecture is a layered architecture
    composed of the UI layer, a domain layer and a
    services layer
  • Actors, such as the human observer in the
    Monopoly game, generate UI events, such as
    clicking on a button with a mouse to play the
    game. The UI software objects must then react to
    the mouse click event and ultimately cause the
    game to play.
  • From the Model-View Separation Principle, we know
    the UI objects should not contain application or
    "business" logic such as calculating a player's
    move. Therefore, once the UI objects pick up the
    mouse event, they need to delegate the request to
    domain objects in the domain layer.
  • See Chapter 13 for a refresher on this.

21
  • The controller pattern advices us on which object
    in the domain layer should be responsible for
    handling UI-generated and forwarded events.
  • E.g. Recalling the SSD for the Monopoly Game

22
  • This can also be represented schematically by
  • Which domain-level object should be responsible
    for handling the playGame event/method call?
  • The controller pattern advises in these
    circumstances

23
  • The controller pattern
  • Name Controller
  • Problem What first object beyond the UI layer
    receives and coordinates ("controls") a system
    operation?
  • Solution Assign the responsibility to an object
    representing one of these choices
  • Represents the overall "system," a "root object,"
    a device that the software is running within, or
    a major subsystem (these are all variations of a
    facade controller)
  • Represents a use case scenario within which the
    system operation occurs (a use case or session
    controller)
  • In our example
  • Option 1 Represents the overall "system," or a
    "root object such as an object called
    MonopolyGame.
  • Option 1 Represents a device that the software
    is controlling e.g. a phone or a bank cash
    machine (e.g., software class Phone or
    BankCashMachine) it doesn't apply in this case.

24
  • Option 2 Represents the use case or session. The
    use case that the playGame system operation
    occurs within is called Play Monopoly Game. Thus,
    a software class such as PlayMonopolyGameHandler
    (appending "Handler" or "Session" is an idiom
    in OOD).
  • Here option 1 is suitable for the moment since
    there are only a few system operations (but see
    the high cohesion pattern)

25
  • So based on the controller pattern design
    decision we are currently here
  • From here 2 kind of designs can be considered
    depending on their cohesion level cohesion
    (which is linked to coupling) is a measure of the
    relative logical strength of a class
  • If a class is responsible for many logically
    unrelated tasks it has low cohesion
  • If a class is responsible for few, logically
    related tasks it has high cohesion
  • In the same way as we should strive for low
    coupling we should aim for high cohesion

26
  • On our example
  • The left-hand version of MonopolyGame has worse
    cohesion than the right-hand version, since the
    MonopolyGame object does all the work, rather
    than delegating and distributing work among
    objects. This leads to the principle of High
    Cohesion, which is used to evaluate different
    design choices.

27
  • The high cohesion pattern
  • Name High Cohesion
  • Problem How to keep objects focused,
    understandable, and manageable, and as a side
    effect, support Low Coupling?
  • Solution Assign responsibilities so that
    cohesion remains high. Use this to evaluate
    alternatives.
  • 17.7 The GRASP
  • GRASP stands for General Responsibility
    Assignment Software Patterns Craig Larman
    there are 9 such OOD patterns
  • Creator, Information Expert, Low coupling,
    Controller, High Cohesion, Polymorphism, Pure
    Fabrication, Indirection, Protected Variations
  • We now see the first 5 in more details, and we
    will apply them more systematically on our case
    studies in the next chapter. The remaining four
    patterns will be seen later.

28
  • Recall the POS domain model (from chapter 9)

29
  • 17.8 The Creator Pattern
  • It helps with the creation of objects a very
    common activity obviously. The proper assignment
    of object creation responsibilities can support
    low coupling, and overall cleaner, simpler
    designs.
  • Creator Pattern
  • Problem Who should be responsible for creating a
    new instance of some class?
  • Solution Assign class B the responsibility to
    create an instance of class A (to make B the
    creator of A objects) if one of these is true
  • B contains, compositely aggregates, or records A.
  • B closely uses A.
  • B has the initializing data for A that will be
    passed to A when it is created. Thus B is an
    Expert with respect to creating A.

30
  • E.g. in the POS case study, who should be
    responsible for creating a SalesLineItem
    instance?
  • by Creator, Sale is a good candidate to have the
    responsibility of creating SalesLineItem
    instances
  • Other choices are possible e.g. the Register
    (since it is the information expert here), but
    that would increase the coupling in the design
  • Composite aggregates Part, Container contains
    Content and Recorder records Recorded all very
    common relationships between classes. Creator
    suggests that the enclosing container or recorder
    class is a good candidate for the responsibility
    of creating the thing contained or recorded.
  • Sometimes you can identify a creator by looking
    for the class that has the initializing data that
    will be passed in during creation.

31
  • 17.9 The Information Expert Pattern
  • During object design, when the interactions
    between objects are defined, we make choices
    about the assignment of responsibilities to
    software classes. If we've chosen well, systems
    tend to be easier to understand, maintain, and
    extend, and our choices afford more opportunity
    to reuse components in future applications.
  • Expert Pattern
  • 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.
  • E.g. in the POS case study, some object needs to
    know the grand total of the current sale
  • Always start by stating clearly the problem Who
    should be responsible for knowing the grand total
    of a sale?

32
  • By expert, we should look for that class of
    objects that has the information needed to
    determine the total.
  • What information do we need? We need to know
    about all the SalesLineItem instances of a sale
    and the sum of their subtotals.
  • Therefore, by expert, a Sale object, since it
    contains all the SalesLineItem instances, should
    be responsible for knowing the grand total of a
    Sale.
  • Next, who should be responsible for knowing the
    subtotal of a SalesLineItem?
  • What information do we need? We need the quantity
    of items being purchased and its price (from
    ProductDescription class).
  • Therefore, by expert, a SalesLineItem should
    determine the subtotal (since it knows its
    quantity and is associated with the appropriate
    ProductDescription).
  • In terms of an interaction diagram, this means
    that the Sale should send getSubtotal messages to
    each of the SalesLineItems and sum the results

33
  • We are not finished yet! To fulfill the
    responsibility of knowing and answering its
    subtotal, a SalesLineItem has to know the product
    price.
  • The ProductDescription is an information expert
    on answering its price therefore, SalesLineItem
    sends it a message asking for the product price.

34
  • The expert pattern is obviously used all the
    time it not always right however, or may lead to
    several candidate classes

35
  • 17.10 The Low Coupling Pattern
  • Coupling is a measure of how strongly one element
    is connected to, has knowledge of, or relies on
    other elements.
  • A class with low coupling is not dependent on too
    many (subjective) other classes, and has simple
    relationships with them.
  • A class with high coupling relies on many other
    classes. This is undesirable because
  • Forced local changes because of changes in
    related classes.
  • Harder to understand in isolation.
  • Harder to reuse because its use requires the
    additional presence of the classes on which it is
    dependent.
  • Low Coupling Pattern
  • Problem How to support low dependency, low change
    impact, and increased reuse?
  • Solution Assign a responsibility so that coupling
    remains low. Use this principle to evaluate
    alternatives.

36
  • E.g. in the POS case study, consider the
    following classes Payment, Register and Sale,
    assume we need to create a Payment instance and
    associate it with the Sale. What class should be
    responsible for this?
  • Since a Register "records" a Payment in the
    real-world domain, the Creator pattern suggests
    Register as a candidate for creating the Payment.
    The Register instance could then send an
    addPayment message to the Sale, passing along the
    new Payment as a parameter

37
  • Another solution is
  • Both work. Both are correct. But which is best?
  • Design 1, in which the Register creates the
    Payment, adds coupling of Register to Payment
    Design 2, in which the Sale does the creation of
    a Payment, does not increase the coupling. (see
    domain model for current coupling)

38
  • Hence here the low coupling pattern helps us to
    steer away from less desirable design It just
    points us in the right direction.
  • Low Coupling encourages you to assign a
    responsibility so that its placement does not
    increase the coupling to a level that leads to
    the negative results that high coupling can
    produce.
  • A class hierarchy based on inheritance
    (superclass/subclasses) creates strong coupling
    and must be used with care i.e. only when it is
    logical to do so, not just for the sake of it.
  • Low Coupling supports the design of classes that
    are more independent (a very very good thing).
  • The low coupling pattern must kept in check by
    the high cohesion pattern otherwise we may end
    up with one class that does all the work (no
    coupling at all!!!). Remember too that our
    classes must not become too big.

39
  • In general, classes that are inherently generic
    in nature and with a high probability for reuse
    should have especially low coupling.
  • High coupling to stable elements and to pervasive
    elements is seldom a problem. E.g. coupling to
    development kit classes, or class libraries.
  • On the other hand high coupling to elements that
    are unstable, is to be avoided.
  • The notion of coupling is fundamental to modular
    designs in general the level of coupling must be
    kept in check not be higher than is necessary.

40
  • 17.11 The Controller Pattern
  • System operations are the major input events
    generated by actors.
  • For example, when a cashier using a POS terminal
    presses the "End Sale" button, he is generating a
    system event indicating "the sale has ended."
    Similarly, when a writer using a word processor
    presses the "spell check" button, he is
    generating a system event indicating "perform a
    spell check."
  • A controller is the first object beyond the UI
    layer that is responsible for receiving or
    handling a system operation message.
  • This is in accordance with the understanding that
    the UI layer shouldn't contain application logic,
    UI layer objects must delegate work requests to
    another layer.

41
  • Controller Pattern
  • Problem What first object beyond the UI layer
    receives and coordinates ("controls") a system
    operation?
  • Solution Assign the responsibility to a class
    representing one of the following choices
  • Represents the overall "system," a "root object,"
    a device that the software is running within, or
    a major subsystem (aka a facade controller).
  • Represents a use case scenario within which the
    system event occurs, often named
    ltUseCaseNamegtHandler, ltUseCaseNamegtCoordinator,
    or ltUseCaseNamegtSession (use case or session
    controller).
  • Use the same controller class for all system
    events in the same use case scenario.
  • Informally, a session is an instance of a
    conversation with an actor. Sessions can be of
    any length but are often organized in terms of
    use cases (use case sessions).

42
  • E.g. in the POS case study, during analysis, we
    discovered many system-level operations
    endSale(), enterItem(), makeNewSale(),
    makePayment(), for which we wrote contracts

43
  • Who should be the controller for system events
    such as enterItem and endSale?
  • By the Controller pattern, here are some choices
  • Represents the overall "system," "root object,"
    device, or subsystem Register
  • Represents a receiver or handler of all system
    events of a use case scenario
    ProcessSaleHandler
  • So
  • which?
  • At this stage it does not really matter, but
    lets see what may happen later more and more
    system operations are considered and since we
    prefer to keep the same controller class for all
    system events within a use case the following
    will occur

44
(No Transcript)
45
  • We prefer to use the same controller class for
    all the system events of one use case so that the
    controller can maintain information about the
    state of the use case. Such information is
    useful, for example, to identify out-of-sequence
    system events (for example, a makePayment
    operation before an endSale operation). Different
    controllers may be used for different use cases.
  • 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.
  • Facade controllers are suitable when there are
    not "too many" system events.
  • If you choose a use case controller, then you
    will have a different controller for each use
    case. This kind of controller is not a domain
    object it is an artificial construct to support
    the system (a Pure Fabrication in terms of the
    GRASP patterns). For example, if the NextGen
    application contains use cases such as Process
    Sale and Handle Returns, then there may be a
    ProcessSaleHandler class and so forth.

46
  • A common defect in the design of controllers
    results from over-assignment of responsibility
    it does do many unrelated work and does not
    delegate enough. A controller then suffers from
    low cohesion, violating the principle of High
    Cohesion (e.g. see the previous Register class
    for example). We call these bloated controllers
  • Use case controllers are a good choice when there
    are many system events across different
    processes. They can replace a bloated facade
    controller.
  • Or ensure that your controller delegates as much
    as possible.
  • For the POS case study, the Register might
    initially be chosen as controller, and we could
    ensure that most of the work is delegated. But we
    should keep in mind that it may become bloated in
    which case we may revert to use case controllers
    instead later. See general principle on next
    figure.

47
(No Transcript)
48
  • 17.12 The High Cohesion Pattern
  • Cohesion is a measure of how strongly related and
    focused the responsibilities of an element are.
    An element with highly related responsibilities
    that does not do a tremendous amount of work has
    high cohesion. These elements include classes,
    subsystems, and so on.
  • High Cohesion Pattern
  • Problem How to keep objects focused,
    understandable, and manageable, and as a side
    effect, support Low Coupling?
  • Solution Assign a responsibility so that cohesion
    remains high. Use this to evaluate alternatives.
  • A class with low cohesion does many unrelated
    things or does too much work. Such classes are
    undesirable they suffer from the following
    problems
  • hard to comprehend
  • hard to reuse
  • hard to maintain
  • delicate constantly affected by change

49
  • E.g. in the POS case study, recalling the
    previous example
  • Or as a sequence diagram
  • This assignment of responsibilities places the
    responsibility for making a payment in the
    Register. The Register is taking on part of the
    responsibility for fulfilling the makePayment
    system operation.

50
  • In this isolated example, this is acceptable but
    if we continue to make the Register class
    responsible for doing some or most of the work
    related to more and more system operations, it
    will become increasingly burdened with tasks and
    become incohesive.
  • Imagine fifty system operations, all received by
    Register. If Register did the work related to
    each, it would become a "bloated" incohesive
    object.
  • The other alternative, which as seen keeps the
    coupling low,

by delegating the payment creation responsibility
to the Sale, also supports higher cohesion in the
Register...
51
  • So, since the second design supports both high
    cohesion and low coupling, it is desirable.
  • Low coupling and high cohesion often go hand in
    hand, they usually reinforce each other
  • Of course the opposite is often true high
    coupling goes with low cohesion thats to be
    avoided.
  • Beyond correctness, the quality of an OO design
    is strongly related to its level of coupling and
    cohesion
  • Many small design decisions are made during OOD,
    each one must be evaluated against the two
    evaluative low coupling and high cohesion
    patterns
  • A poor design is not something that can be easily
    fixed afterwards...

52
  • The only contraindication to the low coupling,
    high cohesion patterns is in relation to
    performance.
  • In fact while our classes should in general be
    quite small and cohesive this can lead to a
    fine-grained OOD (which is good most of the time
    loads of small classes, a rich set of classes)
  • However this leads to communications overheads
    and is therefore maybe not suited for the
    innermost core of an application (e.g. we
    probably should not model each pixel as an object
    ...)
  • A compromise must be reached but in general we
    must go for a large set of small, cohesive, lowly
    coupled classes.

53
  • 17.13 Conclusions
  • Weve introduced here the notion of design
    patterns, performed some design activities, and
    review 5 patterns in detail
  • Creator
  • Information Expert
  • Low coupling
  • Controller
  • High Cohesion
  • These are the most basic, most useful, OOD
    patterns.
  • In the next chapter we will see a systematic way
    to use them to end up with more often than not, a
    correct, good style OOD.
Write a Comment
User Comments (0)
About PowerShow.com