The Decorator Pattern attaches additional
responsibilities to an object dynamically.
Decorators provide a flexible alternative to
subclassing for extending functionality
The Decorator Pattern provides an alternative to subclassing for extending behavior. This is possible
with a set of decorator classes that are used to wrap concrete components. These
Decorator classes are of the same type as the components and therefore mirror the type of the components they decorate.
This is done either through inheritance or interface implementation. Decorators change the behavior of their components by adding
new functionality before and/or after (or even in place of) method calls to the component.
Using the decorator design pattern can result in many small objects, and overuse can be complex.
On its own, the decorator pattern adds a lot of small classes to a design which can be
hard to understand. It also has typing problems which arise when code is dependent on a specific type,
which is destroyed when using decorators. Decorators are typically transparent to the client of the
component. That is, unless the client is relying on the component’s concrete type. To avoid this
drawback other design patterns such as the factory pattern are helpful.
In the following example Beverage acts as a abstract component class.
The concrete components implement this interface.
Another concrete component.
To extend the behavior of these concrete components the following condiment decorator inherits the Beverage base class
and has a member of type Beverage.
Using these classes it is possible to wrap the concrete components which gives them
new behaviors. Note that this is not obtained through direct inheritance.
The next two code snippets show concrete decorators that implement the CondimentDecorator interface.
Another condiment decorator.
And another one.
To instantiate a concrete component, or in this example, a beverage and decorate it with condiments,
the following main class can be executed.
Starting this application results in the following output.