What 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:
- a development process (UP)
- an organizational metaphor (RDD)
- a visual modeling notation (UML)
The Nine GRASP Patterns
- Information Expert
- Low Coupling
- High Cohesion
- Pure Fabrication
- Protected Variations
1. GRASP Creator
Object creation is one of the most common OO activities. (However, set aside for now such concerns as “Factory Method” vs. “Abstract Factory”). GRASP “Creator” principle is meant to help us achieve:
- low coupling
- increased clarity
- increased encapsulation
- increased reusability
- 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).
Consider above example, sale will contain many SalesLineItem objects. Creator GRASP pattern suggests Sale is one object that could fulfill this responsibility.
- MakeLineItem becomes a method in Sale.
- We capture this decision in our UML design-model diagrams
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?
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.
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
2. GRASP Information Expert
Key Idea: Start assigning responsibilities by clearly stating the responsibility.
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?
- Information encapsulation
- low coupling
- behavior is distributed across classes (i.e., high cohesion)
- Low coupling
- High cohesion
3. GRASP Low Coupling
- Assign a responsibility so that coupling remains low.
- Use this principle to evaluate alternative assignment of responsibilities.
- Real-world domain: Register records a Payment (Creator?)
- Also in real-world: A Register also records Sales.
- (Creator) Suggests Register as a candidate for creating Payments.
- (Information Expert) Register knows about Payments, and therefore associates these with Sales
- 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
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 are that these are stable and they are widespread.
4. GRASP Controller
- class is “root object” for overall system (or major subsystem)
- a new class based on use case name
- System events generated by some GUI
- We do not write to the GUI just yet, but assume some UI layer
- 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)
5. GRASP High Cohesion
- Assign a responsibility so that cohesion remains high.
- As with low coupling, use this evaluate alternatives to placing responsibilities in objects
Classes that do too many unrelated things or which do 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).
- Large class maintained by a single programmer
- Distributed systems. Any place where the overhead of invoking an operation is a significant proportion of performing the operation
6. GRASP Polymorphism
- How can we handle alternatives based on type?
- How can we create pluggable software components?
- “Alternatives based on type”: 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?
- 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.
Consider a NextGen POS use case specifies multiple external third-party tax calculators:
- 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?
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
What we obtain via subclassing. Range of possible types usable is finite (Also: this is what we get with overloading)
7. GRASP Pure Fabrication
- 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?
8. GRASP Indirection
- 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?
9. GRASP Protected Variations
- 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.
Also called “Don’t 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
- Singleton Design Pattern
- Strategy Design Pattern
- Abstract Factory Design Pattern
- Factory Method Design Pattern
- Prototype Design Pattern
- Observer Design Pattern
- NULL Object Design Pattern
- Learn to use Design Patterns
- Introduction to Programming in JAVA
- Java Language Basics: Operators and Constructs
- PHP vs Java: Which is for me?
- Object Oriented Programming Concepts in Java
Popular Posts (last 30 days)
- Circular Linked Lists 1300 view(s)
- Attendance Management Sys… 1065 view(s)
- Applications of Stack in … 1058 view(s)
- Graph Implementation in C… 904 view(s)
- Implementing Stack Data S… 775 view(s)
- Simple Currency Converter… 661 view(s)
- GRASP Design Patterns 501 view(s)
- Recursive Factorial funct… 490 view(s)
- Finding Minimum, Maximum … 364 view(s)
- Implementation of Priorit… 310 view(s)
TagsAndroid C-Sharp C/C++ language Classes Data structures Design Pattern Eclipse Game Development Graphics Design Books HTML iPhone JAVA JAVA GUI MIPS Assembly Mobile Programming Books Object Oriented PDF PHP Programming Programming Books Programming Languages Books Python RaphaelJS REST Source Code Threads Tutorial Web Development Books