17.8. A Short Example of Object Design with GRASP
Following sections explore GRASP in more detail, but let's start with a shorter example to see the big ideas, applied to the Monopoly case study. There are nine GRASP patterns; this example applies the following subset:
- Creator
- Information Expert
- Low Coupling
- Controller
- High Cohesion
All the GRASP patterns are summarized on the inside front cover of this book.
Creator
Problem: Who creates the
Square object?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? Now, any object can create a Square , but what would many OO developers choose? And why?How about having a Dog object (i.e., some arbitrary class) be the creator? No! We can feel it in our bones. Why? Becauseand this is the critical pointit doesn't appeal to our mental model of the domain. Dog doesn't support low representational gap (LRG ) between how we think of the domain and a straightforward correspondence with software objects. I've done this problem with literally thousands of developers, and virtually every one, from India to the USA, will say, "Make the Board object create the Squares ." Interesting! It reflects an "intuition" that OO software developers often (exceptions are explored later) want "containers" to create the things "contained," such as Boards creating Squares .By the way, why we are defining software classes with the names Square and Board, rather than the names AB324 and ZC17 ? Answer: By LRG. This connects the UP Domain Model to the UP Design Model, or our mental model of the domain to its realization in the domain layer of the software architecture.With that as background, here's the definition of the Creator pattern[7]:
[7] Alternate creation patterns, such as Concrete Factory and Abstract Factory , are discussed later.
Name: | Creator |
Problem: | Who creates an A? |
Solution: (this can be viewed as advice) | Assign class B the responsibility to create an instance of class A if one of these is true (the more the better):
|
Figure 17.3. Monopoly iteration-1 domain model.
Figure 17.4. Applying the Creator pattern in a dynamic model.
Figure 17.5. In a DCD of the Design Model,
Board has a composite aggregation association with Squares . We are applying Creator in a static model.Information Expert
Problem: Who knows about a
Square object, given a key?The pattern Information Expert (often abbreviated to Expert) is one of the most basic responsibility assignment principles in object design.Suppose objects need to be able to reference a particular Square , given its name. Who should be responsible for knowing a Square , given a key? Of course, this is a knowing responsibility, but Expert also applies to doing .As with Creator, any object can be responsible, but what would many OO developers choose? And why? As with the Creator problem, most OO developers choose the Board object. It seems sort of trivially obvious to assign this responsibility to a Board , but it is instructive to deconstruct why, and to learn to apply this principle in more subtle cases. Later examples will get more subtle.Information Expert explains why the Board is chosen:
Name: | Information Expert |
Problem: | What is a basic principle by which to assign responsibilities to objects? |
Solution: (advice) | Assign a responsibility to the class that has the information needed to fulfill it. |
Figure 17.6. Applying Expert.
Low Coupling
Question: Why
Board over Dog?Expert guides us to assign the responsibility to know a particular Square , given a unique name, to the Board object because the Board knows about all the Squares (it has the informationit is the Information Expert). But why does Expert give this advice?The answer is found in the principle of Low Coupling. Briefly and 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.The Low Coupling principle applies to many dimensions of software development; it's really one of the cardinal goals in building software. In terms of object design and responsibilities, we can describe the advice as follows:
Name: | Low Coupling |
Problem: | How to reduce the impact of change? |
Solution: (advice) | Assign responsibilities so that (unnecessary) coupling remains low. Use this principle to evaluate alternatives. |
Figure 17.7. Evaluating the effect of coupling on this design.
[View full size image]
Key Point: Expert Supports Low Coupling To return to the motivation for Information Expert: it guides us to a choice that supports Low Coupling. Expert asks us to find the object that has most of the information required for the responsibility (e.g., Board ) and assign responsibility there.If we put the responsibility anywhere else (e.g., Dog ), the overall coupling will be higher because more information or objects must be shared away from their original source or home, as the squares in the Map collection had to be shared with the Dog , away from their home in the Board . |
Please note a few UML elements in the sequence diagram in Figure 17.7:
- The return value variable sqs from the getAllSquares message is also used to name the lifeline object in sqs : Map<Square> (e.g., a collection of type Map that holds Square objects). Referencing a return value variable in a lifeline box (to send it messages) is common.
- The variable s in the starting getSquare message and the variable s in the later get message refer to the same object.
- The message expression s = get(name) : Square indicates that the type of s is a reference to a Square instance.
Controller
A simple layered architecture has a UI layer and a domain layer, among others. 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 (in Java for example, a JFrame window and a JButton button) 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 (forward the task to another object) the request to domain objects in the domain layer .Model-View Separation p. 209 The Controller pattern answers this simple question: What first object after or beyond the UI layer should receive the message from the UI layer?To tie this back to system sequence diagrams, as a review of Figure 17.8 shows, the key system operation is playGame . Somehow the human observer generates a playGame request (probably by clicking on a GUI button labeled "Play Game") and the system responds.
Figure 17.8. SSD for the Monopoly game. Note the
playGame operation.[8] Similar objects, messages, and collaboration patterns apply to .NET, Python, etc.
Figure 17.9. Who is the Controller for the
playGame system operation?[View full size image]
Do you see the connection between the SSD system operations and the detailed object design from the UI to domain layer? This is important. |
Name: | Controller |
Problem: | What first object beyond the UI layer receives and coordinates ("controls") a system operation? |
Solution: (advice) | Assign the responsibility to an object representing one of these choices:
|
Represents the overall "system," or a "root object"such as an object called MonopolyGame .Option 1 :
Represents a device that the software is running withinthis option appertains to specialized hardware devices such as a phone or a bank cash machine (e.g., software class Phone or BankCashMachine ); it doesn't apply in this case.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 OO design when this version is used).Option #1, class MonopolyGame , is reasonable if there are only a few system operations (more on the trade-offs when we discuss High Cohesion). Therefore, Figure 17.10 illustrates the design decision based on Controller.
Figure 17.10. Applying the Controller patternusing
MonopolyGame . Connecting the UI layer to the domain layer of software objects.High Cohesion
Based on the Controller decision, we are now at the design point shown in the sequence diagram to the right. The detailed design discussion of what comes nextconsistently and methodically applying GRASPis explored in a following chapter, but right now we have two contrasting design approaches worth considering, illustrated in Figure 17.11.
Figure 17.11. Contrasting the level of cohesion in different designs.
[View full size image]
Name: | High Cohesion |
Problem: | How to keep objects focused, understandable, and manageable, and as a side effect, support Low Coupling? |
Solution: (advice) | Assign responsibilities so that cohesion remains high. Use this to evaluate alternatives. |