Skip to main content

The “Gang of Four” Decorator Pattern: What Is Its Appropriate Use?

Printer-friendly version

Review of Pattern Sections

“Attach additional responsibilities to an object dynamically.” “Dynamically” seems to imply something different from the static division into types and subtypes which is the typical result of decomposition analysis using Generalization and Delegation. Of course, Decorator is different in that it is applied at run-time rather than being defined as a part of the static design. Indeed, this dynamic quality is considered an advantage by proponents of Decorator since it means that assignments of functionality can be very flexible. However, greater flexibility in this respect comes at the price of less structure.

“Decorators provide a flexible alternative to subclassing for extending functionality.” This sentence lies at the heart of the differing interpretations. On the surface it seems to place Decorator as an equal and equivalent alternative to using Generalization for defining subtypes. However, one must note that the Intent section is characterized by very terse and simple statements which therefore might not convey the full sense of what was intended.

In particular, the authors might have said the same thing here based on quite a different perspective. For example, in analyzing the a set of objects in the problem space, one might observe that one could identify at least three different types of functionality:

  1. Static Subtypes: Functionality which was statically divisible into and associated with some number of fixed subtypes;
  2. Separate Static Responsibilities: Functionality which can be statically separated into a coherent hierarchy independent of the other variations in the main set; and
  3. Dynamic Variations: Functionality which was dynamically associated with a subtype, i.e., it did not always apply to every object in the subclass or it might apply to a particular object only for a limited time and unpredictable combinations of functionality might be needed by individual objects.

One viewpoint is that the first type is typically addressed with Generalization; the second with Delegation; and the third with Decorator. Thus, one might make the statement in the GoF book based on the notion that the third type of functionality was not easily handled with Generalization and so Decorator was a “flexible alternative” for functionality in that category. One can’t determine which was meant from this one sentence alone, so we need to look at the overall context provided in the pattern for clarification.

Also Known As
This section provides no specific insight except to provide an alternate name, “Wrapper”.

“Sometimes we want to add responsibilities to individual objects, not to an entire class.” This seems to reinforce the dynamic character noted in the Intent and seems to clearly separate Decorator from the kinds of subtype distinctions which one makes with Generalization since those are static and all objects in the inheritance hierarchy will always belong to a particular subtype.

“A graphical user interface toolkit, for example, should let you add properties like borders or behaviors like scrolling to any user interface component.” This seems to introduce a further wrinkle on the functionality types in that the same functionality is applicable to multiple component types. This is clearly something which would not fit in a normal Generalization hierarchy.

GoFDecorator_20100222.pdf127.66 KB