Java Reference
In-Depth Information
RumWithSpices
•
VodkaWithHoney
•
VodkaWithSpices
•
WhiskeyWithHoney
•
WhiskeyWithSpices
•
WhiskeyWithHoneyAndSpices
•
Note that we have already listed eleven classes and the list is not complete yet. Consider ordering whiskey with
two servings of honey. You can see that the number of classes involved is huge. If you add some more drinks and
flavorings, the classes will increase tremendously. With this class design, you will have a problem maintaining the
code. If the price of honey changes, you will need to revisit every class that has honey in it and change its price. This
design will produce a class explosion. Fortunately, there is a design pattern to deal with such a problem. It is called the
decorator
pattern. Typically, classes are organized as shown in Figure
7-1
to use the decorator pattern.
Figure 7-1.
A generic class diagram based on the decorator pattern
The decorator pattern requires you to have a common
abstract
superclass from which you inherit your
concrete component classes and an
abstract
decorator class. Name the common superclass
Component
.
You can use an interface instead of an
abstract
class. Concrete components, shown as
ConcreteComponentA
and
ConcreteComponentB
in the class diagram, are inherited from the
Component
class. The
Decorator
class
is the
abstract
decorator class, which is inherited from the
Component
class. Concrete decorators, shown as
ConcreteDecoratorA
and
ConcreteDecoratorB
in the class diagram, are inherited from the
Decorator
class. The
Decorator
class keeps a reference to its superclass
Component
. The reference of a concrete component is passed to a
concrete decorator as an argument in its constructor as follows:
ConcreteComponentA ca = new ConcreteComponentA();
ConcreteDecoratorA cd = new ConcreteDecoratorA(ca);