This document describes the Decorator design pattern. The Decorator pattern allows behavior to be added to individual objects dynamically at runtime by wrapping them in decorator objects that contain the added behavior. This provides a flexible alternative to subclassing for extending functionality. Decorators work by maintaining a reference to a component object and conforming to the same interface as the component. Requests are forwarded to the component and decorators can perform additional actions before and after forwarding.
Long journey of Ruby standard library at RubyConf AU 2024
Stoop 439-decorator
1. S.Ducasse 1
QuickTime™ and aTIFF (Uncompressed) decompressorare needed to see this picture.
Stéphane Ducasse
Stephane.Ducasse@univ-savoie.fr
http://www.listic.univ-savoie.fr/~ducasse/
Decorator
3. S.Ducasse 3
Decorator
• Attach additional responsib
• ilities to an object dynamically.
• Decorators provide a
• flexible alternative to
• subclassing for extending
• functionality.
• Aka:Wrapper
4. S.Ducasse 4
Decorator Intent
• Attach additional responsib ilities to an object
dynamically.
• Decorators provide a flexible alternative to
• subclassing for extending functionality.
• Aka:Wrapper
6. S.Ducasse 6
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...
7. S.Ducasse 7
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
9. S.Ducasse 9
Applicability
• When responsibilities can be withdrawn
• When responsibilities can be added transparently
• When subclassing is not possible (combination
explosion)
11. S.Ducasse 11
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.
12. S.Ducasse 12
Collaborations
• Decorator forwards requests to its Component
object. It may optionally perform additional operations
before and after forwarding the request.
13. S.Ducasse 13
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.
14. S.Ducasse 14
Consequences
• More flexibility than static inheritance. Dynamic
addition of properties
• Avoids feature-laden classes high up in the hierarchy.
• Lots of little objects.
15. S.Ducasse 15
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
17. S.Ducasse 17
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.
18. S.Ducasse 18
Known Uses
• VisualWorks Wrapper hierarchy
• Stream Decorators inVisualWorks:
• BOSSTransporter is a stream decorator
• FormattedStream is a stream decorator