Decorator Design Pattern
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. (dofactory)
- 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.
- The I/O Streams implementations of both Java and the .NET Framework incorporate the decorator pattern.
- GUI toolkits use decoration pattern to add functionalities dynamically
- Object responsibilities and behaviours should be dynamically modifiable
- Concrete implementations should be decoupled from responsibilities and behaviours
- Provide new behavior at run-time for individual objects as an alternative for subclassing.
- Adding additional attributes to an object dynamically.
- The decorations can be composed together in a mix-and-match fashion.
- Decorators can be an effective substitute for multiple-inheritance.
- Overuse of the Open/Closed principle can lead to abstract and complex code. This principle should really only be used in places where code is least likely to change.
- Decorators can lead to a system with a lot of smaller objects that will look similar to a developer and introduce a maintenance headache.
- The Decorator and it's enclosed components are not identical, so tests for object type (instanceof) will fail.
- Decoration adds functionality to objects at runtime which would make debugging system functionality harder.
- When you have multiple inputs & outputs, decorating something becomes much harder.
- Adapter provides a different interface to its subject. Proxy provides the same interface. Decorator provides an enhanced interface in terms of object’s responsibilities. Decorator is thus more transparent to the client. As a consequence, Decorator supports recursive composition, which is not possible with pure Adapters.
- Composite and Decorator have similar structure diagrams, reflecting the fact that both rely on recursive composition to organize an open-ended number of objects. A Decorator can be viewed as a degenerate Composite with only one component. However, a Decorator adds additional responsibilities - it is not intended for object aggregation. Decorator is designed to let you add responsibilities to objects without subclassing. Composite’s focus is not on embellishment but on representation. These intents are distinct but complementary. Consequently, Composite and Decorator are often used in concert.
- Composite could use Chain of Responsibility to let components access global properties through their parent. It could also use Decorator to override these properties on parts of the composition.
- Decorator and Proxy have different purposes but similar structures. Both describe how to provide a level of indirection to another object, and the implementations keep a reference to the object to which they forward requests.
- Decorator lets you change the skin of an object. Strategy lets you change the guts.