Design Patterns - Decorator
Decorator is a structural design pattern that lets you attach additional behaviors to objects dynamically.
Decorator is a structural design pattern that lets you attach new behaviors to objects dynamically by placing these objects inside special wrapper objects that contain the behaviors. By using Decorator a user can can add new functionality to an existing object without altering its structure. This pattern acts as a wrapper to an existing class so it also known as Wrapper.
- Attach additional responsibilities to an object dynamically.
- Decorators provide a flexible alternative to subclassing for extending functionality.
Sometimes we need 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 behaviours like scrolling to any user interface component.
One way to add responsibilities is with inheritance. Inheriting a border from another class puts a border around every subclass instance. This is inflexible, however, 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.
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.
Transparency lets you nest decorators recursively, thereby allowing an unlimited number of added responsibilities.
For example, suppose we have a TextView object 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. We simply compose the decorators with the TextView to produce the desired result
The ScrollDecorator and BorderDecorator classes are subclasses of the 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.
Decorator subclasses are free to add operations for specific functionality.
The important aspect of this pattern is that it lets decorators appear anywhere a VisualComponent can.
That way clients generally can't tell the difference between a decorated component and an undecorated one, and so they don't depend at all on the decoration.
Use the Decorator pattern when
- To add responsibilities to individual objects dynamically and transparently, that is, without affecting other objects.
- for responsibilities that can be withdrawn.
- when extension by subclassing is impractical. Sometimes a large number of independent extensions are possible and would produce an explosion of subclasses to support every combination. Or a class definition may be hidden or otherwise unavailable for subclassing.
Wearing clothes is an example of using decorators. When you’re cold, you wrap yourself in a sweater. If you’re still cold with a sweater, you can wear a jacket on top. If it’s raining, you can put on a raincoat. All of these garments “extend” your basic behavior but aren’t part of you, and you can easily take off any piece of clothing whenever you don’t need it.
Decorator forwards requests to its Component object. It may optionally perform additional operations before and after forwarding the request.
- Component - defines the interface for objects that can have responsibilities added to them dynamically.
- ConcreteComponent - 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 - adds responsibilities to the component.
Thank you for reading.
Did you find this article valuable?
Support Balasundar by becoming a sponsor. Any amount is appreciated!