This question was asked already here, but rather than answering the specific question, descriptions of how the decorator pattern works were given instead. I'd like to ask it again because the answer is not immediately evident to me just by reading how the decorator pattern works (I've read the wikipedia article and the section in the book Head First Design Patterns).
Basically, I want to know why an abstract decorator class must be created which implements (or extends) some interface (or abstract class). Why can't all the new "decorated classes" simply implement (or extend) the base abstract object themselves (instead of extending the abstract decorator class)?
To make this more concrete I'll use the example from the design patterns book dealing with coffee beverages:
Beverage
HouseBlend
simply extend Beverage
CondimentDecorator
class is created which extends Beverage
and has an instance of Beverage
Milk
is created which extends CondimentDecorator
I'd like to understand why we needed the CondimentDecorator
class and why the class Milk
couldn't have simply extended the Beverage
class itself and been passed an instance of Beverage
in its constructor.
Hopefully this is clear...if not I'd simply like to know why is the abstract decorator class necessary for this pattern? Thanks.
Edit: I tried to implement this, omitting the abstract decorator class, and it seems to still work. Is this abstract class present in all descriptions of this pattern simply because it provides a standard interface for all of the new decorated classes?
Better one and a half year late than never:
A base class for decorators of a certain interface is not necessary.
However, it is very useful to have:
for one thing, as a means of documenting that classes derived from it are decorators of the interface in question
but mostly, because decorators usually do not need to add functionality to every single method of the decorated interface.
So, a base decorator class allows derived decorators to implement only those methods of the interface to which they actually need to add some functionality, leaving the rest of the methods to the base class to provide a default implementation for. (Which simply delegates the call to the decoree.)
Contrast this with writing decorators that implement the decorated interface from scratch, where the compiler requires that you provide an implementation for every single method of the interface, whether your decorator will be adding any functionality to it, or not.
It is that simple, really.