Head First Design Patterns ch03.pdf
(
1505 KB
)
Pobierz
chapter3NewNew.indd
3
the DecoratorPattern
h
g
Decorating Objects
g
I used to think real men
subclassed everything. That was
until I learned the power of
extension at runtime, rather than
at compile time. Now look at me!
Just call this chapter “Design Eye for the Inheritance Guy.”
We’ll re-examine the typical overuse of inheritance and you’ll learn how to decorate
your classes at runtime using a form of object composition. Why? Once you know the
techniques of decorating, you’ll be able to give your (or someone else’s) objects new
responsibilities
without making any code changes to the underlying classes.
this is a new chapter
79
the starbuzz
story
Welcome to Starbuzz Coffee
Starbuzz Coffee has made a name for itself as the
fastest growing coffee shop around. If you’ve seen one
on your local corner, look across the street; you’ll see
another one.
Because they’ve grown so quickly, they’re scrambling
to update their ordering systems to match their
beverage offerings.
When they first went into business they designed their
classes like this...
Beverage
is s
et in e
ach su
bclass
and ho
lds a
description
des
criptio
n of t
he bev
erage,
like
The c
ost()
meth
od is
abstr
act; s
ubclas
sses
need
to de
fine t
heir
own i
mplem
entat
ion.
“Mo
st Ex
cellent
Dark
Roast
”.
The
getDes
criptio
n() me
thod
retur
ns the
descr
iption.
getDescription()
cost()
// Other useful methods...
HouseBlend
DarkRoast
Decaf
Espresso
cost()
cost()
cost()
cost()
Each subclas
s implements cost() to return th
e cost of the beverage.
80
Chapter 3
The
descr
iption
instan
ce var
iable
the
decorator
pattern
In addition to your coffee, you can also ask for several condiments like
steamed milk, soy, and mocha (otherwise known as chocolate), and have
it all topped off with whipped milk. Starbuzz charges a bit for each of
these, so they really need to get them built into their order system.
Here’s their first attempt...
Beverage
description
getDescription()
cost()
// Other useful methods...
HouseBlendWithSteamedMilk
andMocha
DarkRoastWithSteamedMilk
andMocha
DecafWithSteamedMilk
andMocha
EspressoWithSteamedMilk
andMocha
HouseBlendWithSteamedMilk
andCaramel
cost()
cost()
cost()
cost()
HouseBlendWithWhipandMocha
EspressoWithSteamedMilk
andCaramel
cost()
DecafWithSteamedMilk
andCaramel
DarkRoastWithSteamedMilk
andCaramel
cost()
cost()
EspressoWithWhipandMocha
HouseBlendWithMocha
cost()
DarkRoastWithWhipandMocha
cost()
DecafWithWhipandMocha
HouseBlendWithSoyandMocha
cost()
EspressoWithMocha
HouseBlendWithSteamedMilk
andSoy
cost()
DarkRoastWithMocha
cost()
DecafWithMocha
cost()
cost()
EspressoWithSteamedMilk
andSoy
DecafWithSoy
HouseBlendWithSoy
cost()
cost()
cost()
DecafWithSteamedMilk
andSoy
HouseBlendWithSteamedMilk
cost()
DarkRoastWithSteamedMilk
andSoy
cost()
EspressoWithSteamedMilk
cost()
cost()
HouseBlendWithWhip
cost()
DarkRoastWithSoy
cost()
DecafWithSteamedMilk
cost()
DarkRoastWithSteamedMilk
DecafWithSoyandMocha
DarkRoastWithSoyandMocha
DarkRoastWithSoy
cost()
cost()
DecafWithSoy
cost()
cost()
HouseBlendWithSteamedMilk
andWhip
cost()
DecafWithSoyandMocha
EspressoWhip
cost()
cost()
cost()
HouseBlendWithWhipandSoy
cost()
DarkRoastWithWhip
DecafWithWhip
cost()
cost()
cost()
cost()
EspressoWithSteamedMilk
andWhip
cost()
DecafWithSteamedMilk
andWhip
DarkRoastWithSteamedMilk
andWhip
EspressoWithWhipandSoy
cost()
DarkRoastWithWhipandSoy
cost()
DecafWithWhipandSoy
cost()
cost()
cost()
cost()
Whoa!
Can you say
“class explosion?”
you are here
4
81
cost()
violating
design
principles
A
brain
power
It’s pretty obvious that Starbuzz has created a maintenance nightmare for
themselves. What happens when the price of milk goes up? What do they do
when they add a new caramel topping?
Thinking beyond the maintenance problem, which of the design principles that
we’ve covered so far are they violating?
This is stupid; why do we need
all these classes? Can’t we just use
instance variables and inheritance in
the superclass to keep track of the
condiments?
Well, let’s give it a try. Let’s start with the Beverage base
class and add instance variables to represent whether or
not each beverage has milk, soy, mocha and whip...
Beverage
description
milk
soy
mocha
whip
New boolean va
lues for
each condiment
.
Now we’ll implem
ent cost() in Beverage (instead of
keeping it abstr
act), so that it can calculate the
costs associated
with the condiments for a partic
ular
beverage instanc
e. Subclasses will still override
cost(), but they
will also invoke the super version
so
that they can c
alculate the total cost of the ba
sic
beverage plus th
e costs of the added condiments.
getDescription()
cost()
hasMilk()
setMilk()
hasSoy()
setSoy()
hasMocha()
setMocha()
hasWhip()
setWhip()
// Other useful methods..
82
Chapter 3
Plik z chomika:
wubudubu1
Inne pliki z tego folderu:
using.design.patterns.in.game.engines.PDF
(25 KB)
Wiley - Business Modeling with UML - Business Patterns at Work (2000).pdf
(4024 KB)
Wiley - The Art of Software Architecture.pdf
(6523 KB)
The Object-Oriented Modeling Process Process Patterns For An Architecture-Driven Approach.pdf
(85 KB)
Software Pattern - Design Patterns explained.pdf
(8120 KB)
Inne foldery tego chomika:
Inżynieria Oprogramowania
IO
Zgłoś jeśli
naruszono regulamin