Pattern:
Decorator


Author

Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides

Intent

"Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality." (Gamma, E., R. Helm, R. Johnson, and J. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Reading, MA: Addison-Wesley, 1995)

Motivation

Sometimes we want to add responsibilities to individual objects, not to an entire class. A graphical user interface toolkit, for example, should let you add properties like borders or behaviors like scrolling to any user interface component. An approach to accomplishing this is to enclose the component in another object that adds the border. The enclosing object is called a decorator. The decorator conforms to the interface of the component it decorates so that its presence is transparent to the components clients. The decorator forwards requests to the component and may perform additional actions (such as drawing a border) before or after forwarding. Transparency lets you nest decorators recursively, thereby allowing an unlimited number of added responsibilities. Suppose we have a TextView object (ConcreteComponent in the thumbnail) that displays text in a window. TextView has no scroll bars by default, because we might not always need them. When we do, we can use a ScrollDecorator to add them. Suppose we also want to add a thick black border around the TextView. We can use a BorderDecorator to add this as well. The ScrollDecorator and BorderDecorator classes (ConcreteDecorator in in thumbnail) are subclasses of Decorator, an abstract class for visual components that decorate other visual components. VisualComponent (Component in the thumbnail) is the abstract class for visual objects. It defines their drawing and event handling interface. The Decorator class simply forwards draw requests to its component. Decorator subclasses can extend this operation. The important aspect of this pattern is that it lets decorators appear anywhere a VisualComponent can. Clients generally cant tell the difference between a decorated component and an undecorated one, and so they dont depend on the decoration.

Known Uses

To add graphical embellishments to widgets, many object-oriented user interface toolkits use this pattern. For example, InterViews, ET++, ObjectWorks\Smalltalk class library DebuggingGlyph from InterViews and PassivityWrapper from ParcPlace Smalltalk.

See Also

Adapter, Composite, and Strategy patterns

Thumbnail

Keywords

Composite pattern, Decorator pattern, Strategy pattern, structural patterns, Gamma patterns, Adapter Class pattern, Adapter Object pattern, Wrapper pattern, forward requests, recursive composition, object (adding responsibilities), component decoration

Business Domains

any system requiring dynamic behavioral assignments to objects

Problem Forces

extending behaviors of an existing hierarchy is impracticalneed to modify object behaviors dynamically without affecting existing objects

Benefits

allows you to vary the behavior of a class independent of its contextgreater flexibility than inheritance-based behavioral extensionsreduces subclassing

Liabilities

may be difficult to debug because of the number of similar classesresults in many small objects looking very similar

Implementation Files

Test driver Test.javaSimple implementation of the pattern - Decorator class. Decorator.javaSimple implementation of the pattern - ConcreteDecoratorB class. ConcreteDecoratorB.javaSimple implementation of the pattern - ConcreteDecoratorA class. ConcreteDecoratorA.javaSimple implementation of the pattern - ConcreteComponent class. ConcreteComponent.javaSimple implementation of the pattern - Component class. Component.javaTest driver testdecorator.cppSimple implementation of the pattern. decorator.h



Generated on Fri Oct 20 10:45:54 GMT+02:00 2000 by Framework Studio