Title: GRASP Patterns
1GRASP Patterns
2Challenge
- Old-school advice on OOD
- After identifying your requirements and creating
a domain model, then add methods to the
appropriate classes, and define the messages
between the objects to fulfill the requirements. - New-school advice there are consequences to
- where we place methods
- they way objects interact in our design
- specific principles can help us make these
decisions - Note This is not UML!
- UML is a notation
- Larman The critical design tool for software
development is a mind well educated in design
principles.
3Recall The big picture
- Object design is part of the larger modeling
effort - some inputs to modeling
- Whats been done?
- How do things relate?
- How much design modeling to do, and how?
- What is the output?
- Domain models, SDDs
- some outputs from modeling
- object design (UML diagrams interaction, class,
package) - UI sketches and prototypes
- database models
- sketches of reports and prototypes
4Design of objects
- Responsibility-driven design (RDD)
- What are an objects responsibilities?
- What are an objects roles?
- What are an objects collaborations?
- The term is important
- We are initially trained to think objects in
terms of data structures and algorithms
(attributes and operations) - RDD shifts this by treating objects as having
roles and responsibilities - Objects then become
- service providers
- information holders
- coordinators, controllers
- interfaces, etc.
5What is an object responsibility?
- Doing
- doing something itself (creating an object
performing 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
- Responsibilities vary in granularity
- big (hundreds of classes) example provide
access to relational databases - small (one method) example create an instance
of Sale
6What is an object collaboration?
- Assumption
- responsibilities are implemented by means of
methods - the larger the granularity of responsibility, the
larger the number of methods - this may entail an object interacting with itself
or with other objects - Therefore
- fulfilling responsibilities requires
collaborations amongst different methods and
objects - Low representational gap
- RDD is a metaphor
- Objects are modeled as similar to persons /
systems with responsibilities - Community of collaborating responsible objects
7A couple of parenthetical comments
- Responsibility here implies non-interference
- This is idealized (i.e., in the real world this
is not necessarily true in boundary cases) - However it is suitable enough for object design
- Suitable for programming-in-the-large
- As opposed to programming-in-the-small
- This is a qualitative difference
- mass of details
- amount of communication
- this become overwhelming
- Practical as opposed to theoretical
8GRASP
- Craig Larmans methodical approach to OO design
- In essence
- a tool to help apply responsibilities to OOD
design - designed (and meant to be used as) methodical,
rational, explainable techniques - They are patterns of assigning responsibilities
- Note the use of pattern here is slightly
different from some that intended by the GoF book - Recognizes that responsibility assignment is
something already do - UML interaction diagrams are about assigning
responsibilities
9A bit more about pattern terminology
- Patterns as applied to architecture
- invented by Christopher Alexander
- context that of a pattern language for
designing spaces used by humans - Classic design patterns for software
- invented by the Gang of Four (GoF) (Gamma,
Johnson, Helm, Vlissides) - Patterns is now a rather loose term
- Conferences exist to look at patterns
- http//hillside.net/plop/2005/
- Larman has a special meaning for his GRASP
patterns
10What is a GRASP pattern?
- A named and well-known problem/solution pair
- General enough to be applied to new contexts
- Specific enough to give advice on how to apply it
- Especially important for novel situations
- Also comes with a discussion of
- trade-offs
- implementations
- variations
11Specifically GRASP
- Defines nine basic OO principles
- basic building blocks for OO designs
- Meant to be pragmatic
- Meant to be a learning aid
- aids naming the group of ideas
- aids in presenting insight of ideas
- aids in remembering basic, classic design ideas
- Also intended for combination with
- a development process (UP)
- an organizational metaphor (RDD)
- a visual modeling notation (UML)
12The Nine GRASP Patterns
- Creator
- Information Expert
- Low Coupling
- Controller
- High Cohesion
- Polymorphism
- Pure Fabrication
- Indirection
- Protected Variations
131. GRASP Creator
Problem Who should be responsible for creating a
new instance of some class? Example Who is
responsible for creating SalesLineItem?
- Object creation is one of the most common OO
activities - (However, set aside for now such concerns as
Factory Method vs. Abstract Factory) - Creator principle is meant to help us achieve
- low coupling
- increased clarity
- increased encapsulation
- increased reusability
Recall We also have a Register class floating
about.
14Jargon alert terms and definitions
coupling the degree to which each program module
relies on other modules
cohesion a measure of how well the operations in
a module work together to provide a specific
piece of functionality
encapsulation synonym for information hiding
reusability likelihood a segment of structured
code can be used again to add new functionality
with slight or no modification
151. GRASP Creator
- Problem statement
- 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 if one of these is true (
the more the better) - B contains or compositely aggregates A.
- B records A
- B closely uses A.
- B has initializing data for A (i.e., B is an
Expert with respect to creating A).
161. GRASP Creator
Who is responsible for creating SalesLineItem?
- Sale will contain many SalesLineItem objects
- Creator GRASP pattern suggests Sale is one object
that could fulfill this responsibility. - Consequences
- makeLineItem becomes a method in Sale.
- we capture this decision in our UML design-model
diagrams
17GRASP patterns give you more
- Each of these patterns comes with
- a discussion section
- a contraindication section
- a benefits section
- a related patterns or principles section
- Important!
- these patterns provide advice on assignment of
responsibilities - patterns may conflict in their advice
- there we must exercise some judgment in applying
these patterns - the extra sections help us with thi
- This is not mechanical work!
181. GRASP Creator
- Discussion
- intent is to support low coupling (i.e., creator
is found that already needs to be connected to
created object) - initializing data is sometimes an indicator of a
good Creator - some object constructors have complex signatures
- which objects have the information needed to
supply parameter values for such constructors? - Contraindications
- creation can be complex (recycled instances,
creating an instance from a family of similar
classes) - may wish to use Factory Method or Abstract
Factory instead in these cases
191. GRASP Creator
- Benefits
- low coupling has already been mentioned
- why is this good?
- Related patterns or principles
- Low Coupling
- Factory Method and Abstract Factory
- Whole-Part pattern defines aggregate objects
that support encapsulation of components
20Reality Check
212. GRASP Information Expert
- Problem statement What is a general principle of
assigning responsibilities to objects? - Recall design model may end up very large
(hundreds of classes and methods) - If assignment of responsibilities is well chosen,
result is an easy to understand system - Solution
- Assign a responsibility to the information expert
- This expert is the class that has the information
needed to fulfill the responsibility
22Key idea
(Clear Statement Rule) Start assigning
responsibilities by clearly stating the
responsibility.
232. GRASP Information Expert
- NextGEN POS will end up with lots of
functionality - One small part of this is class that knows the
grand total of a sale - Clear Statement rule could transform this into
- Who should be responsible for knowing the grand
total of a sale? - Which class of objects has the information needed
to determine the total?
If there are relevant classes in the design
model, then look there first for classes
otherwise look into the Domain Model in order
to us or expand its representations to suggest
the creation of appropriate classes
242. GRASP Information Expert
new method
new method
252. GRASP Information Expert
new method
26Comment
- Notice how the initial assignment of
responsibilities drove the design - Result is the identification of several new
methods - Interaction diagram helped us capture the result
- Class model entities are also modified
- Also notice the degree of delegation
- getSubtotal (vs. getPrice and getQuantity
to supply a multiplication operation)
272. GRASP Information Expert
- Read text for full details on patterns
- Discussion
- Contraindications (important!)
- Benefits
- Information encapsulation
- low coupling
- behavior is distributed across classes (i.e.,
high cohesion) - Related Patterns
- Low coupling
- High cohesion
283. GRASP Low Coupling
- Problem
- How can our design support
- low dependency?
- low change impact?
- increased reuse?
- Solution
- Assign a responsibility so that coupling remains
low. - Use this principle to evaluate alternative
assignment of responsibilities.
29Key idea
Coupling affects global understanding, but
decisions about placing responsibility must be
made more locally, usually by choosing from
amongst alternatives.
30Example
- NextGen POS dealing with Payments
- What object should be responsible for
associating Payments with Sales? - Three objects appear to be involved
- Real-world domain Register records a Payment
(Creator?) - Also in real-world A Register also records
Sales.
31Example
- Suppose we apply our two previous GRASP patterns
like so - (Creator) Suggests Register as a candidate for
creating Payments. - (Information Expert) Register knows about
Payments, and therefore associates these with
Sales - Resulting interaction diagram appears below
32Example
- Recall Our GRASP pattern is to be applied to
alternatives. - Another approach
- (Creator) Suggests Sales creates Payments
33Evaluating Alternatives
Which design choice results in lower coupling?
34Kinds of Coupling
- Often applied to types or classes
- Class X has an attribute referring to Class Y
instance - Class X objects call on the services of a Class Y
object - Class X has methods referencing instances of
Class Y (i.e., parameters, local variables of
Class Y) - Class X is a direct or indirect subclass of Class
Y - Y is an interface, and Class X implements it
- Note
- All of these are needed at some point
- We are not trying to eliminate coupling, but
rather make careful choices
35Important contra-indicator
- There is a least one set of objects and classes
to which we must allow our code to be
highly-coupled - Java libraries (i.e., javax.swing, java.util)
etc. - C libraries
- .NET libraries
- Key features permitting this
- these are stable
- they are widespread
364. GRASP Controller
- Problem
- What first object beyond the UI layer receives
and coordinates (controls) a system operation? - Solution
- Assign responsibility to a class based on one of
the following - class is root object for overall system (or
major subsystem) - a new class based on use case name
37Context
- This usually is applied to the actions recorded
in our SSDs - system events generated by some GUI
- we do not write to the GUI just yet, but assume
some UI layer - Therefore we do not have window, view or
document classes - Be very careful here as we are so tied to GUIs
when visualizing applications - GUI is meant to delegate tasks to system
38Example (NextGen POS)
Which class of object should be responsible for
receiving the enterItem() system event message?
Register? POSSystem? These represent overall
system, root object, device, or subsystem.
ProcessSaleHandler?ProcessSaleSession?(these
would be new) These represent a receive or
handler of all system events of a use case
scenario.
39Example NextGen POS
Here are the two basic alternatives.
(And how do we choose from amongst them?)
40Caveats
- A balance must be striked between having too many
controllers and too few - More common problem too few (i.e., bloated
controllers) - Example
- single controller classes for all events (façade)
- controller performs many of the events itself
rather than delegate work - controller maintain a lot of state about the
system (e.g., variables and attributes)
415. GRASP High Cohesion
- Problem
- How can we keep objects in our design
- focused?
- understandable?
- manageable?
- Solution
- Assign a responsibility so that cohesion remains
high. - As with low coupling, use this evaluate
alternatives to placing responsibilities in
objects
42Signs of Low Cohesion
- Classes that do too many unrelated things or
which too too much work - Such classes are
- hard to comprehend
- hard to reuse
- hard to maintain
- delicate in that any change elsewhere in the
system requires many changes in this class - In general
- the greater the granularity of classes, the lower
the cohesion - but we do not want to go to the other extreme
(i.e., lots and lots of classes, each doing one
trivial thing)
43Compare and contrast
(Yet again) What class should be responsible for
creating and class instance and associating it
with a Sale?
We have two options. Which shows both high
cohesion and low coupling?
44Contra-indicators
- Simple people-management issues
- Large class maintained by a single programmer
- Performance
- Distributed systems
- Any place where the overhead of invoking an
operation is a significant proportion of
performing the operation
456. GRASP Polymorphism
- Problem
- How can we handle alternatives based on type?
- How can we create pluggable software components?
- Alternatives based on type
- Old style conditional variation (if-then-else,
examination of tags, type testing) - Pluggable software components
- Usually applied to client-server relationships
- How can we replace one server component with
another and not need to rewrite the client?
466. GRASP Polymorphism
- Solution
- Use object type to declare alternative behavior.
- Then use polymorphic operations to define the
alternative behavior - Insight We no longer need to test for object
type, instead allowing compiler run-time system
to do this work for us. - We have seen one important flavour of this
already - Always program to an interface and not to a
concrete instance.
47NextGen POS example taxes
- A NextGen POS use case specifies multiple
external third-party tax calculators - Tax-Master
- Good-As-Gold Tax Pro
- others as yet unknown
- Intent is to have system integrate with each of
these - Each tax calculator, however, has a different
interface - Solution?
48Polymorphism via Adapter
49Polymorphism slight detour
- Parametric polymorphism
- What we obtain using generics
- Example
- Creating a list of integers vs. a list of
instances of class B - List operations are not re-written for different
types - Impossible to insert an integer onto a list for
class B instances - Range of possible types usable is infinite
- Ad-hoc polymorphism
- What we obtain via subclassing
- Range of possible types usable is finite
- (Also this is what we get with overloading)
50Polymorphism interfaces
- Single-inheritance languages
- Java, C Class may have only one superclass
- Difficult to mix in behaviors or capabilities
- Multiple-inheritance languages
- C, Eiffel
- May now mix in behaviors, but this can have
unintended consequences - Interfaces
- Provides the mix in capability of multiple
inheritance - but without some of the major problems with
multiple inheritnace.
516. GRASP Polymorphism
- Contraindicators
- May not need to future proof the code (or at
least not as much as we think) - Cute
- Novice developers tend toward brittle designs
- intermediate developers tend toward overly
fancy and flexible, generalized ones - and expert designers choose with insights
perhaps a simple and brittle design whose cost of
change is balance against likelihood of change
527. GRASP Pure Fabrication
- Problem
- What object should have the responsibility, when
you do not want to violate High Cohesion and Low
Coupling, or other goals - yet solutions offered by Expert or other GRASP
patterns are not appropriate - Insight here
- low representational gap aids design
- but this can lead to serious problems later if
applied without enough thought
537. GRASP Pure Fabrication
- Solution
- Create an artificial or convenience class
- and assign a highly cohesive set of
responsibilities to it. - This class is literally a fabrication (i.e.,
made out of whole cloth) - As we have total freedom in creating such a
class, we get much of what we want by way of
cohesion and coupling
54Example NextGen POS
- Sales we need to save them in a relational
database - Where do we place this functionality?
- Beware
- Such a task may require use of a lot of database
operations which, of course, have nothing to do
with sales - Sale class would be coupled with a database API
- Saving data is actually a very general task are
we willing to duplicate this functionality across
our design? - Solution PersistentStorage class
55PersistentStorage
- This solves several design problems
- Sale remains well designed, with high cohesion
and low coupling - PersistentStorage class is itself relatively
cohesive (i.e., sole purpose is storing or
inserting objects in some persistent storage
medium) - PersistentStorage is generic and may be used by
other classes - Note emphasis is on where responsibility should
be placed
56Decomposition
- Representational decomposition
- Use to achieve a low representational gap
- Objects in the software system have rough
analogues in the domain - Example Sale
- Behavioral decomposition
- Use when we want to assign responsibilities by
grouping behaviors or by grouping algorithms - Example PersistentStorage
- Pure Fabrications are (mostly) function centric
or behavior based - That said, GoF patterns are Pure Fabrications
577. GRASP Pure Fabrication
- Contraindications
- Pure Fabrication tends to be preferred by novice
designers - Also preferred by those new to object-oriented
programming - Example all functions simply become objects
- Overuse of Pure Fabrication could lead to too
many behavioral objects
588. GRASP Indirection
- Problem
- Where do we assign a responsibility such that we
avoid direct coupling between two or more things? - Recall
- Coupling is necessary in systems
- But too much coupling results in brittleness
- When we are aware of possible brittleness, how do
we deal with it?
598. GRASP Indirection
- Solution
- Assign responsibility to an intermediate object.
- This object mediates between other components
or services. - Therefore object and services are not directly
coupled - Classic example use of Adapter GoF pattern
- Another example PersistentStorage from previous
GRASP pattern - Practically every one of the GoF patterns
involves indirection - Most problems in computer science can be solved
with an additional level of indirection.
609. GRASP Protected Variations
- Problem
- How can we design
- objects
- subsystems
- and systems
- such that the variations in these do not have
an undesirable impact on other elements in the
system? - Solution
- Identify points of predicted variation or
instability - Assign responsibilities to create a stable
interface around them. - This principle is simply the source of most
software engineering wisdom.
61Protected Variations mechanisms
- Core mechanisms
- data encapsulation
- interfaces
- polymorphism
- indirection
- standards
- Data-Driven designs
- Service Lookup
- Interpreter-Driven Designs
- Reflective / Meta-level Designs
62Protected Variations mechanisms
- Uniform Access
- Standard Languages
- Liskov Substitution Principle (formalism)
63Law of Demeter
- Also called Dont Talk to Strangers by Larman
- Law states that, within a method, message
should only be sent to the following objects - The this object
- A parameter of the method.
- An attribute of this
- An element of a collection which is an attribute
of this - An object created within the method
64Law of Demeter violations
class Register private Sale sale
public void slightlyFragileMethod()
Money amount sale.getPayment().getTenderedAmo
unt() // //
public void moreFragileMethod()
AccountHolder holder
sale.getPayment().getAccount().getAccountHolder()
public void poison() F someF
foo.getA().getB().getC().getD().getE().getF()
65Motivation behind Demeter
- Traversing path of object connections ? talking
to a distant stranger - Design impact
- code is now coupled to a specific structure of
object connections - the farther along the path a program traverses,
the more fragile the code is - In some situations, long traversals are not
necessarily bad - i.e., standard libraries (Java, STL)
66Protected Variations
- Two other ways of stating this
- information hiding (Parnas)
- open-closed principle (Meyer)
- Protection at variation and evolution points.
67The Nine GRASP Patterns
- Creator
- Information Expert
- Low Coupling
- Controller
- High Cohesion
- Polymorphism
- Pure Fabrication
- Indirection
- Protected Variations