Applied Design Patterns with Java
Structural :: Decorator (175) {C ch 12}
Intent
Attach additional responsibilities to an object dynamically.
Decorators
provide a flexible alternative to subclassing for extending functionality.
As Known As
Wrapper
Motivation
Decorator
adds responsibilities to individual objects, not to
an entire class. A GUI toolkit allows adding properties
like borders or behaviors like scrolling to user interface components. Inheriting a border from another class
puts a border around every subclass instance. This is inflexible because the choice of border is made statically.
A client can't control how and when to decorate the component with a border. A more flexible approach is to enclose
the component in another object that adds the border. The enclosing object is called a Decorator,
and it conforms to the interface of the component it decorates so that its presence is transparent to the
component's clients. The Decorator forwards requests to the component and may perform additional actions
(such as drawing a border) before or after forwarding. Transparency allows nesting decorators recursively, for
an unlimited number of added responsibilities.
A TextView object displays text in a window. TextView has no scroll bars by default, because it might not always
need them. But a ScrollDecorator can be used to add them. Suppose we also want to add a thick black border around
the TextView. A BorderDecorator can be used to add this as well. The following object diagram shows how to compose
a TextView object with BorderDecorator and ScrollDecorator objects to produce a bordered, scrollable text view:
The ScrollDecorator and BorderDecorator classes are subclasses of Decorator, an abstract class for visual components that decorate other visual components.
VisualComponent 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, and Decorator subclasses extend this operation. Decorator subclasses
are free to add operations for specific functionality. ScrollDecorator's ScrollTo operation lets other objects
scroll the interface if they know there happens to be a ScrollDecorator object in the interface. The important
aspect of this pattern is that it lets Decorators appear anywhere a VisualComponent can. Clients generally can't tell the difference between a decorated component and an undecorated
one, so they don't depend at all on the decoration.