Java Reference
In-Depth Information
// Have Whiskey with Honey
Drink d2 = new Honey(new Whiskey());
printReceipt(d2);
// Have Vodka with Spices
Drink d3 = new Spices(new Vodka());
printReceipt(d3);
// Have Rum with double Honey and Spices
Drink d4 = new Spices(new Honey(new Honey(new Rum())));
printReceipt(d4);
}
public static void printReceipt(Drink drink) {
String name = drink.getName();
double price = drink.getPrice();
System.out.println(name + " - $" + price);
}
}
Whisky - $1.5
Whisky, Honey - $1.75
Vodka, Spices - $1.3
Rum, Honey, Honey, Spices - $1.5
You need to consider the other aspects of the decorator pattern:
•
The
abstract Component
class (the
Drink
class in the example) can be replaced by an
interface. Note that you have included two instance variables in the
Drink
class. If you want to
replace the
Drink
class with an interface, you must move these two instance variables down
the class hierarchy.
•
You may add any number of new methods in abstract decorators and concrete decorators to
extend the behavior of its component.
•
With the decorator pattern, you end up with lots of small classes, which may make your
application hard to learn. However, once you understand the class hierarchy, it is easy to
customize and use them.
•
The goal of the decorator pattern is achieved by having a common superclass for the concrete
components and concrete decorators. This makes it possible for a concrete decorator to
be treated as a component, which in turn allows for wrapping a decorator inside another
decorator. While constructing the class hierarchy, you can introduce more classes or remove
some. For example, you could have introduced a class named
MainDrink
between the
Drink
class, and
Rum
,
Vodka
and
Whiskey
classes.
The concrete decorator need not be inherited from an
•
abstract
decorator class. Sometimes
you may want to inherit a concrete decorator directly from the
abstract Component
class. For
example, the
ObjectInputStream
class is inherited from the
InputStream
class in the
java.
io
package, not from the
FilterInputStream
class. Please refer to Figure
7-5
for details. The
main requirement for a concrete decorator is that it should have the
abstract
component
as its immediate or non-immediate superclass and it should accept an
abstract
component
type argument in its constructor.