Transcript Chapter 1

Chapter 25
aytoachieveprotectionat a
Lowcouplingisaw
variationpoint.
ariation
rotectedV
P
echanism
M
P
S
A
R
G
les
cip
rin
P
aytoachieveprotectionat a
orphismisaw
olym
P
.
aytoachievelowcoupling
variationpoint, andaw
.
aytoachievelowcoupling
nindirectionisaw
A
oupling
LowC
echanism
M
ohesion
ighC
H
echanism
M
Indirection
echanism
M
ure
P
abrication
F
dapter designpatternisakindof Indirection
heA
T
.
orphism
olym
, that usesP
abrication
ureF
andaP
orphism
olym
P
ple
xam
E
dapter
A
n
esig
FD
o
G
s
attern
P
More Grasp Principles


Chapter 17 covers Information Expert,
Creator, High Cohesion, Low Coupling
and Controller
This chapter covers Polymorphism,
Indirection, Pure Fabrication and
Protected Variations.
More Grasp Principles

Polymorphism:



Handle alternatives based on type
Create pluggable software components
Corollary:

Do not handle code variations using
conditional logic
Fig. 25.1
«interface»
ITaxCalculatorAdapter
getTaxes( Sale ) : List<TaxLineItems>
TaxMasterAdapter
GoodAsGoldTaxPro
Adapter
<???>Adapter
...
...
getTaxes( Sale ) : List<TaxLineItems>
getTaxes( Sale ) : List<TaxLineItems>
By Polymorphism, multiple tax calculator adapters have
their own similar, but varying behavior for adapting to
different external tax calculators.
Fig. 25.2
NOTE: We need {abstract} notation unless there is default behaviour
that can be defined in the Square superclass
More Grasp Principles


If Square receives the landedOn()
message, who sends it?
Since Player knows its location after a
move, it is the info expert so give it the
job of sending the message
loc.landedOn(player)
Fig. 25.3
coupling between Player and Square has increased but not doubled
Fig. 25.4
Why should Player addCash()


Human Players are responsible for their cash so the
Player class gets this responsibility by LRG.
Hence by Expert, addCash() belongs to Player too.
Fig. 25.5
When landedOn() does nothing?


We need this or the magic of polymorphism doesn't work.
Declaring Square.landedOn() abstract won't work
either.
Fig. 25.6
Where is tax calculation done?

As in the case of adding cash, the Player knows about
cash (LRG) and so is the info expert and gets the job.
Fig. 25.7
Who changes a player location?

A player knows its location so will have to know its
new location. By info expert it gets the job.
Coupling Problems





Recall that in Chapter 18, it was Piece that knew its
location and not Player.
Now Player needs to extract location from Piece and
replace it with a new location.
Remember, it is Player who sends the landedOn()
message.
Refactoring Opportunity: when object A repeatedly
needs data from object B it implies that either A
should hold that data or B should do A's job.
Solution: Do away with Piece.
When to use Interfaces?




Polymorphism implies the use of interfaces even when
a language doesn't support them.
In Java, introduce an interface when you want to use
polymorphism but you don't want to commit to a
particular class hierarchy.
Rule of Thumb: If you have a declared abstract class
AC with some public interface then it is always good
to create a specific interface class IC and have AC
implement it.
The above allows you to subclass AC or implement IC
as is convenient.
When NOT to use Interfaces?



Some times we introduce interfaces and polymorphism to
protect ourselves against future changes in requirements.
If such change is not likely then you may be doing a lot
of extra work for nothing.
However, there are benefits:
 extensions are easy to add
 clients are unaffected by new implementations
Pure Fabrication:






Trying not to violate High Cohesion/Low Coupling but
other GRASP principles don't seem appropriate?
There are situations in which LRG doesn't work or
leads to low cohesion, for example.
Solution: Assign a highly cohesive set of responsibilities
to an artificial class.
We call this class a pure fabrication.
Some times the new class comes about because the
programmed solution has responsibilities that doe not
exist in the real world situation.
For example, a Sale object handles an actual sale but
saving this data to a database needs to go elsewhere
for cohesion reasons.
Pure Fabrication:

Problems Solved:
 Untouched class remains well-designed, hopefully
with high cohesion and low coupling
 New class is cohesive by design
Pure Fabrication Example:





Who rolls the dice in Monopoly?
Currently, Player rolls the dice. Weaknesses:
– Dice are reusable but in our design Player adds the
total so code has limited reuse capability.
– If you ask for the roll total you need to roll again.
No Domain Model object improves on this situation.
Pure Fabrication saves the day – Cup.
Cup is now usable in any number of different games.
Fig. 25.8
Discussion:




Representational vs Behavioural Decomposition (Design)
Classes that come from the Domain Model and exhibit
a LRG are “representationally” motivated.
Classes like Pure Fabrications that encapsulate related
functionality are “behaviourally” motivated.
Adapters and Strategies are examples of behaviourally
motivated classes.
Contraindications:




You can take Behavioural Decomposition too far.
Representational classes need to have behaviour.
Too much Behavioural Decomposition leads to too much
coupling.
Symptom of too much Behavioural Decomposiiton is
the need to pull too much data from different places
in order to do something.
Big Statement:


The author says “virtually all design patterns are pure
fabrications”.
What would make you agree with him?
Fig. 25.9
Indirection:



Problem is to assign a responsibility so as to avoid
direct coupling between two classes.
Decouple two already coupled objects so that reuse
potential remains high.
Solution: Assign a responsibility to an intermediate
class. This class mediates between other classes.
Fig. 25.10
:S
a
le
:
T
a
x
M
a
s
te
r
A
d
a
p
te
r
t=
g
e
tT
o
ta
l
T
C
P
s
o
c
k
e
t
c
o
m
m
u
n
ic
a
tio
n
ta
x
e
s
=
g
e
tT
a
x
e
s
(s
)
x
x
x
...
...
«
a
c
to
r
»
:T
a
x
M
a
s
te
r
S
y
s
te
m
th
e
a
d
a
p
te
ra
c
ts
a
s
a
le
v
e
lo
f
in
d
ir
e
c
tio
n
to
e
x
te
r
n
a
ls
y
s
te
m
s
Indirection Discussion:

Adapters or Pure Fabrication classes like a database
adapter.
“Most problems in computer science can be solved by another
level of indirection.” David Wheeler
“Most problems in performance can be solved by removing another
layer of indirection.” Anonymous

Lots of design patterns use Indirection. Indirection
often arises from Pure Fabrications.
Protected Variations:



Problem: How to design objects so that variations or
instability does not undesirably impact other objects?
Solution: Identify points of predicted variation and assign
responsibilities so as to create a stable “interface”
around them.
Example:
– Adapters hide different APIs.
– Strategies hide different algorithms.
Protected Variations:


You can argue that most of what we do can be called
Protected Variation.
Example:
A
C
A
C
B
Suppose A is coupled to C and C can
vary. The coupling can then impact A.
Now protect C's variation by a Pure
Fabrication – B.
Suppose A is coupled to B and B to
C but B is stable. Now A is protected
from variation in C and there is less
“coupling” overall because B's only
job is to hide C while A has other things
to do so is hampered by its coupling
to C but not by its coupling to B.
Important:



Almost every design pattern and trick in the text is a
specialization of Protected Variations.
Some people call this “information hiding”.
Maturity as a programmer can be seen in your ability to
– employ ever-wider mechanisms to achieve PV,
– pick the appropriate PV battles to fight
– select the best PV solution to a problem
Early Techniques:
encapsulation, interfaces
polymorphism
Later Techniques:
rule-based languages,
rule interpreters,
reflective and metadata
designs
Examples:
Data-driven Designs:
– style sheets, property files, layout documents,
metadata documents are read in and dealt with
programmatically.
 Service Lookup:
– Clients don't need to know service location
 Interpreter-driven Designs:
– a generic program interprets a set of changing
rules
 Meta-Level Designs
– reflective methods for reading meta-data;
introspection
Structure-Hiding:

Don't Talk to Strangers:
– this principle sets out who you can send a message
to inside a method.
– ok: this, parameter, attribute of this, element in a
collection which is an attribute of this, object
created by the method
– not ok:
class Register {
private Sale sale;
public void slightlyFragileMethod() {
// Money is not something we should be coupled with
// Money is a “stranger”
Money amount = sale.getPayment().getTenderedAmount();
// or
F someF = foo.getA().getB().getC().getD().getE().getF();
Unless:

The author notes that long chains like the previous
slide do lead to code with problems unless the objects
involved come from very stable structures like the
Java class libraries.
Thoughts from Famous People:


David Parnas – 1972: Information Hiding
– We propose instead that one begins with a list of
difficult design decisions or design decisions
which are likely to change. Each module is
then designed to hide such a change decision
from others
Bertrand Meyer – 1988: Open-Closed Principle
– Modules should be both open (for extension;
adaptable) and closed (the module is closed
to modification in ways that affect clients).