“Avoids feature-laden classes high up in the hierarchy. Decorator offers a pay-as-you-go approach to adding responsibilities. … Functionality can be composed from simple pieces. As a result, an application needn't pay for features it doesn't use.” This point complements the first point, i.e., faced with entities with complex functionality one option is to create a class which contains all possible functionality as a part of the standard base class, but this is considered undesirable. Decorator provides one approach by which needed functionality can be added as needed to any specific instance For type 3 functionality and one-sided functionality Decorator would appear to be preferrable. Generalization and Delegation provide other ways to manage type 4 crosstab functionality. Selection among these options depends on the context, as will be discussed further in the conclusion.
“A decorator and its component aren't identical.” If one has a need to rely on object identity, Decorator can present a problem since the Component and the Decorator are not the same object, so dynamically wrapping the Component with a new Decorator will dynamically change the identity of the package. This is mostly an issue where one is making dynamic changes in functionality. If the Decorators are applied as a part of the building process and remain in place during the lifecycle of the Component, this is less likely to be an issue.
“Lots of little objects. A design that uses Decorator often results in systems composed of lots of little objects that all look alike.” Of course, one might also have a lot of classes in any design where there is a rich functionality which is used in multiple combinations. However, with Decorator, each unit of functionality is a wrapper for the Component and thus all wrappers are quite similar to one another. If the same functionality is decomposed using Generalization and Delegation, there may be a similar number of total components, but they will be structured into inheritance and collaboration hierarchies rather than simply being a collection of wrappers. With Generalization and Delegation, it will also be clear what combinations are required and allowed, which is not immediately apparent with Decorator and thus must be enforced with logic in the factory. Of course, the factory needs to build the correct Delegates as well, but those dependencies are inherent in the model, while the allowable and required combinations of Decorator must be managed with external logic.
Implementation
“Interface conformance. A decorator object's interface must conform to the interface of the component it decorates. ConcreteDecorator classes must therefore inherit from a common class.” This principle is illustrated in the diagram under Structure in which the Component Class exists to provide a common ancestor for the ConcreteComponent and the Decorator. This class defines the interface presented by the Decorator, except for the additional Decorator-specific interface.
“Omitting the abstract Decorator class.” This point merely notes that the abstract Decorator class can be omitted when there is only a single Decorator.
| Attachment | Size |
|---|---|
| GoFDecorator_20100222.pdf | 127.66 KB |
- Show full page
- Printer-friendly version
- Login or register to post comments
-
- Send to friend

