Grasp
Grasp
• Erich Gamma
• Richard Helm
• Ralph Johnson
• John Vlissides
Name: Creator
Solution: Assign class B the responsibility to create an instance of class A if one of these is:
• B contains or aggregates A (in a collection)
• B records A
• B closely uses A
• B has the initializing data for A
Example:
: Register : Sale
makeLineItem(quantity)
create(quantity) : SalesLineItem
Creator Example:
• Another use: Identify a creator by looking for a class that has the initialization data that will
be passed in during creation.
– Actually an example of the “Expert” pattern
• Initialization data passed in to an “initialization method”
– Often a constructor with parameters
– Or a factory method
• Example:
– A Payment instance, when created needs to be initialized with the Sale total.
– Sale knows Sale total. Good candidate for creating Payment.
Sale
3. Low Coupling
• Name: Low Coupling
• Problem: How to reduce the impact of change on software? How to support low
dependency, low change impact, and increased re-use?
• Solution (advice): Assign responsibilities so that (unnecessary) coupling remains low. Use
this principle to evaluate alternatives.
• Why is a class with high (or strong) coupling bad?
• Forced local changes because of changes in related classes
• Harder to understand in isolation
• Harder to re-use
• Because it requires the presence of classes that it depends on
Evaluating the Effect of Coupling
• Coupling: A measure of how strongly one element is connected to, has knowledge of, or
depends on other elements
• The greater the coupling, the greater the dependence between objects
4. Controller pattern
• Use same controller class for all system events of one use case
– Controller maintains information about the state of the use case
– Helps identify out-of-sequence operations
• Example: makePayment before endSale
Bloated controller:
• Signs of a bloated controller
– There is a single controller receiving many system events
– Controller itself performs the tasks instead of delegating them
– Controller has many attributes, maintains a lot of info about the system or domain
• Better to distribute these to other objects
• Cures :
– Add more controllers
– Design the controller to delegate the work
Desirable controller
presses button
: Cashier
actionPerformed( actionEvent )
1: enterItem(itemID, qty)
Undesirable controller
presses button
Cashier
actionPerformed( actionEvent )
1: makeLineItem(itemID, qty)
Domain Layer :Sale
5. High Cohesion
: Register : Sale
makePayment()
create()
p : Payment
addPayment( p )
makePayment()
makePayment()
create() : Payment
Modular Design:
• Modularity: The property of a system that has been decomposed into a set of cohesive and
loosely coupled modules
• Exceptions to high cohesion and modularity
– Example: To simplify maintenance by one SQL expert, group all SQL-related
functionality of all classes into one separate class
– Distributed server objects: Because of cost of communication, might make sense to
have few, large server objects
• Example: Instead of three fine-grained operations, setName, setSalary,
setHireDate, have one coarse-grained operation, setData
6. Polymorphism
Problem:
To handle alternatives based on types?
Solution:
When alternate behaviours are selected based on the type of an object, use
polymorphic method call to select the behaviour, rather than using if statement to test the
type.
Polymorphism : Example
Example:desirable: Consider a UML diagram drawing program
• If shapes are responsible for drawing themselves via the draw() method:
– Obviously, an Actor (stick figure) will draw itself differently than a UseCase
(ellipse)
– It might make sense in this case to have the classes themselves handle the drawing
by polymorphically overriding the draw() method
– An advantage is that new entities (e.g. State) can be easily added without changing
the core graphics code
• Polymorphism can lead to highly cohesive objects
Example: undesirable
• Consider the example where some draw() method were implemented similarly to this:
If (entity.type = “UseCase”) then
drawEllipse(…);
Else if (entity.type = “Class”) then
drawRectangle(…);
…
End if
• This is not highly cohesive, since it combines unrelated behaviours, and it also strongly
couples this object with the shape it draws
7. Pure Fabrication
Problem:
To not violate High Cohesion and Low Coupling?
Solution:
Assign a highly cohesive set of responsibilities to an artificial class that does not represent
anything in the problem domain, in order to support high cohesion, low coupling, and reuse.
Benefits:
● High cohesion is supported because responsibilities are factored into a class that only
focuses on a very specific set of related tasks.
● Reuse potential may be increased because of the presence of fine grained Pure Fabrication
classes.
Example
Suppose, in the point of sale example, that support is needed to save Sale instances in a
relational database. By Expert, there is some justification to assign this responsibility to Sale
class. However.
• The task requires a relatively large number of supporting database-oriented operations and
the Sale class becomes incohesive.
• The sale class has to be coupled to the relational database increasing its coupling.
• Saving objects in a relational database is a very general task for which many classes need
support. Placing these responsibilities in the Sale class suggests there is going to be poor
reuse or lots of duplication in other classes that do the same thing.
• The Sale remains well design, with high cohesion and low coupling
Pure fabrication
● Preserves low coupling and high cohesion of classes
8. Indirection
Problem:
To avoid direct coupling?
To de-couple objects so that Low coupling is supported and reuse potential remains high?
Solution:
Assign the responsibility to an intermediate object to mediate between other
components or services, so that they are not directly coupled.
Example: PersistentStorageBroker
The Pure fabrication example of de-coupling the Sale from the relational database services
through the introduction of a PersistentStorageBroker is also an example of assigning
responsibilities to support Indirection. The PersistentStorageBroker acts as an intermediary
between the Sale and database