200 likes | 374 Views
Decorator. Decorator. Attach additional responsib ilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. Aka: Wrapper. Decorator Intent. Attach additional responsib ilities to an object dynamically.
E N D
Decorator • Attach additional responsib • ilities to an object dynamically. • Decorators provide a • flexible alternative to • subclassing for extending • functionality. • Aka: Wrapper
Decorator Intent • Attach additional responsib ilities to an object dynamically. • Decorators provide a flexible alternative to • subclassing for extending functionality. • Aka: Wrapper
Motivation • Adding behavior to individual object not entire class • scrollbar • border
Inheritance? • Does not work well • Too much combination border, color, scrollbars, bounds, translation... • To static: Clients cannot control when to put a border or not...
Decorator • Enclose the component into another one that adds border...in another one that adds scrollbar... • The decorator 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
Applicability • When responsibilities can be withdrawn • When responsibilities can be added transparently • When subclassing is not possible (combination explosion)
Participants • Component (VisualComponent) • defines the interface for objects that can have responsibilities added to them dynamically. • ConcreteComponent (TextView) • defines an object to which additional responsibilities can be attached. • Decorator • maintains a reference to a Component object and defines an interface that conforms to Component's interface. • ConcreteDecorator (BorderDecorator, ScrollDecorator) • adds responsibilities to the component.
Collaborations • Decorator forwards requests to its Component object. It may optionally perform additional operations before and after forwarding the request.
About Identity • A decorator and its component aren't identical. • A decorator acts as a transparent enclosure. But from an object identity point of view, a decorated component is not identical to the component itself. • If the decorator is wrapping, then identity of the object may change. • Good at construction time, but else should “adapt” the references from the decorated to the decorator.
Consequences • More flexibility than static inheritance. Dynamic addition of properties • Avoids feature-laden classes high up in the hierarchy. • Lots of little objects.
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 (at least in C++). • Omitting the abstract Decorator class. There's no need to define an abstract Decorator class when you only need to add one responsibility. • Keeping Component classes lightweight. Component should specify an interface, decorators are then easier to define
Wrapping or not? Conforming or not • With decorator • With strategies
Strategies? • Strategies are a better choice when the Component class is heavyweight, thereby making the Decorator pattern too costly to apply. • The Strategy-based approach might require modifying the component to accommodate new extensions. • a strategy can have its own specialized interface, • a decorator's interface must conform to the component's. • A strategy needs only define the interface for rendering a border, which means that the strategy can be lightweight even if the Component class is heavyweight.
Known Uses • VisualWorks Wrapper hierarchy • Stream Decorators in VisualWorks: • BOSSTransporter is a stream decorator • FormattedStream is a stream decorator