Title: More GRASP Patterns
1Chapter 25
2Polymorphism
- Problems
- Handle alternatives based on type if a program
uses if-then-else or case statement conditional
logic and a new variation arises, the case logic
has to be modified (in many places). - Create pluggable software components How can
you replace one server component with another
without affecting the client?
3Polymorphism
- Solution When related alternatives or behaviors
vary by type (class), assign responsibility for
the behavior, using polymorphic operations, to
the types for which the behavior varies. - Do not test for the type of an object and use
conditional logic to perform varying alternatives
based on type. - E.g., in POS application, support third-party tax
calculators with adapter objects.
4Fig. 25.1 Polymorphism in adapting to tax
calculators
5Fig. 25.2 Applying polymorphism to Monopoly
6Fig. 25.3 Applying polymorphism dynamic design
7Fig. 25.4 The GoSquare case
8Fig. 25.5 The RegularSquare case
9Fig. 25.6 The IncomeTaxSquare case
10Fig. 25.7 The GoToJailSquare case
11Pure Fabrication
- Problem To which object should a responsibility
be assigned when assigning it to a domain layer
software class would lead to problems? - E.g., low cohesion, high coupling, low reuse
potential. - Solution Assign a highly cohesive set of
responsibilities to an artificial or convenience
class that does not represent a problem domain
concept.
12Pure Fabrication in the POS Case Study
- What class should be responsible for saving Sale
instances in a relational DB? - Information Expert Have Sale do it. But
- Requires numerous supporting database-oriented
operations unrelated to sale-ness, so
incohesive - Sale has to be coupled to DB interface.
- Many classes need support for saving objects in
DB, so code will be duplicated across classes. - Create new class PersistentStorage.
- Not a domain concept, but convenient for software
developer, and highly cohesive.
13Pure Fabrication in the Monopoly Case Study
- Dice rolling Player rolls all dice and sums
total. - Summing service is not generalized for use in
other games. - Cant ask for current dice total without rolling
again. - Add a Pure Fabrication called Cup to hold dice,
roll them, and know their total. - Not a domain concept from Monopoly, but the name
of the class is relevant to other games.
14Fig. 25.8 Design Class Diagram for a Cup
15Fig. 25.9 Using Cup in Monopoly Game
16Types of Decomposition
- Design of objects Chosen by
- Representational decomposition software class
related to/representing a domain object. - Supports low representational gap.
- E.g., TableOfContents in the domain of books.
- Behavioral decomposition group by behaviors or
by algorithms. - No concern for relating to real-world domain
concept. - E.g., TableOfContentsGenerator is an algorithm
object. - All GoF design patterns are Pure Fabrications.
17Indirection
- Problem How do we assign responsibility to
avoid direct coupling between two or more
classes? - Solution Assign responsibility to an
intermediate object to mediate between other
components or services so that they are not
directly coupled. - Intermediary creates indirection between other
components. - Most problems in computer science can be solved
by another layer of indirection.
18Fig. 25.10 Indirection via an Adapter
19Protected Variations
- Problem How do we design objects, subsystems,
and systems so that the variations or instability
in these elements does not have an undesirable
impact on other elements? - Solution Identify points of predicted variation
or instability assign responsibility to create a
stable interface around them. - E.g., use of polymorphism to implement an adapter
for external tax calculators.
20Mechanisms Motivated by Protected Variations
- Core Protected Variations Mechanisms
- Data encapsulation, interfaces, indirection,
polymorphism, standards, virtual machines - Data-Driven Designs
- Reading parameters from an external source to
change behavior of a system at run time, style
sheets, metadata for object-relational mapping,
property files, reading in window layouts, . . . - Protects by externalizing the variant.
21Mechanisms Motivated by Protected Variations,
cont.
- Service Lookup
- Using naming services or traders to obtain a
service (e.g., Javas JNDI for Jini, or UDDI for
web services). - Protected from variations in location of
services. - A special case of data-driven design.
- Interpreter-Driven Designs
- Interpreters that execute rules/scripts read from
an external source, neural network or constraint
logic networks, . . . - Externalizes the logic, reads, and interprets it.
22Mechanisms Motivated by Protected Variations,
cont.
- Reflective or Meta-Level Designs
- Reflective algorithms that use introspection and
meta-language services. - Another special case of data-driven design.
- Standard Languages
- Official language standards protect against a
proliferation of varying languages. - E.g., SQL
23Mechanisms Motivated by Protected Variations,
cont.
- Uniform Access
- Some languages (Ada, Eiffel, C) support a
syntactic construct (auto getters and setters) so
that both a method and field access are expressed
the same way. - E.g., aCircle.radius could invoke a radius()
method or directly access a public field radius. - Can change from public fields to access methods
without changing client code.
24Liskov Substitution Principle (LSP)
- Software that refers to a type T should work as
expected with any substituted implementation or
subclass of T. - If for each object o1 of type S there is an
object o2 of type T such that for all programs P
defined in terms of T, the behavior of P is
unchanged when o1 is substituted for o2, then S
is a subtype of T. - Formalizes the principle of protection against
variations in different implementations of an
interface, or subclass extensions of a superclass.
25Dont Talk to Strangers (Law of Demeter)
- Within a method, messages should only be sent to
the following objects - The this (or self) object.
- A parameter of the method.
- An attribute of this.
- An element of a collection that is an attribute
of this. - An object created within the method.
- Avoids coupling a client to knowledge of indirect
objects.
26Dont Talk to Strangers An Example
- Avoid creating designs that traverse long object
structure paths. - Mild violation of the principle
- Money amount sale.getPayment().getTenderedAmount
() - Traversing farther along a structural path
- AccountHolder holder sale.getPayment()
.getAccount().getAccountHolder() - More generally
- E someE foo.getA().getB().getC().getD().getE()
- Preferred
- AccountHolder holder sale.getAccountHolderOfPa
yment()
27Points of Change
- Variation point A point of change in the
existing, current system or requirements. - E.g., multiple tax calculator interfaces must be
supported. - Evolution point A speculative point of
variation that may arise in the future, but is
not present in the existing requirements. - Can be documented with UP Change Cases.
- Caution the cost of engineering protection at
evolution points can be higher than reworking a
simple design.
28Information Hiding
- David Parnas, On the Criteria to be Used in
Decomposing Systems into Modules Hide
information about the design from other modules,
at the points of difficulty or likely change. - The same principle as Protected Variations.
- Not simply data encapsulation that is only one
technique to hide information about the design.
29Open-Closed Principle (OCP)
- Bertrand Meyer Modules should be both
- open (for extension adaptable) and
- closed (to modification that affects clients).
- The phrase closed with respect to X means that
clients are not affected if X changes. - E.g., the class is closed with respect to
instance field definitions through the mechanism
of data encapsulation with private fields and
public accessing methods.