Decorator
m (Reverted edits by Ebybymic (Talk); changed back to last version by Mujtaba Alshakhouri) |
|||
(15 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
+ | [[Category:Design Patterns]] | ||
+ | [[Category:Structural Patterns]] | ||
The Decorator pattern makes it possible to add new/additional behavior/functionality to an existing class dynamically. This works by adding a decorator class, which has the same interface as the original (decorated) class. The decorator class wraps the original class which is usually achieved by passing the original object as a parameter to the constructor of the decorator when it is created. | The Decorator pattern makes it possible to add new/additional behavior/functionality to an existing class dynamically. This works by adding a decorator class, which has the same interface as the original (decorated) class. The decorator class wraps the original class which is usually achieved by passing the original object as a parameter to the constructor of the decorator when it is created. | ||
Line 8: | Line 10: | ||
*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. | *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. | ||
− | + | ==Example== | |
A nice example is a webbrowser. A webbrowser is viewing webpages. The webpage itself displays the information and the webbrowser knows nothing about the content of the webpage. So it is possible that the webpage doesn't fit into the webbrowsers window. Therefore windowscrollbars are needed to show the information. However the browser shouldn't assume that scrollbars are always required and certainly it should never assume scrollbars are not needed at all. So scrollbars are just displayed when really required. Thus in this case the decorator adds dynamically scrollbars to the window of the webpage whenever they are needed. | A nice example is a webbrowser. A webbrowser is viewing webpages. The webpage itself displays the information and the webbrowser knows nothing about the content of the webpage. So it is possible that the webpage doesn't fit into the webbrowsers window. Therefore windowscrollbars are needed to show the information. However the browser shouldn't assume that scrollbars are always required and certainly it should never assume scrollbars are not needed at all. So scrollbars are just displayed when really required. Thus in this case the decorator adds dynamically scrollbars to the window of the webpage whenever they are needed. | ||
+ | |||
+ | *You can find [http://java.dzone.com/articles/design-patterns-decorator here] a nicely explained example of the Decorator Pattern usage in the real world along with java code. | ||
==UML-Diagram== | ==UML-Diagram== | ||
Line 16: | Line 20: | ||
==Participating Classes== | ==Participating Classes== | ||
− | ===Component=== | + | ===Component=== |
+ | |||
+ | ''Window'' | ||
+ | |||
Defines the abstract interface of the decorated object which can have added funtionality dynamically. | Defines the abstract interface of the decorated object which can have added funtionality dynamically. | ||
− | ===ConcreteComponent=== | + | ===ConcreteComponent=== |
+ | |||
+ | ''SimpleWindow'' | ||
+ | |||
Defines an object to which additional behaviour can be attached. | Defines an object to which additional behaviour can be attached. | ||
− | ===Decorator=== | + | ===Decorator=== |
+ | |||
+ | ''WindowDecorator'' | ||
+ | |||
Maintains a reference to the Component and defines a interface which complies to the Components interface. | Maintains a reference to the Component and defines a interface which complies to the Components interface. | ||
− | ===ConcreteDecorator=== | + | ===ConcreteDecorator=== |
+ | |||
+ | ''HorizontalScrollbarDecorator,VerticalScrollbarDecorator'' | ||
+ | |||
Adds new functionality to the Component | Adds new functionality to the Component | ||
== Recognising the pattern == | == Recognising the pattern == | ||
− | '''Classes:''' Component, | + | '''Classes:''' ''Component'', ''ConcreteComponent'', ''Decorator'', ''ConcreteDecorator'' |
* Inheritance hierarchy that has a Component interface. | * Inheritance hierarchy that has a Component interface. | ||
* Decorator class has protected/private Component field that holds one Component instance. | * Decorator class has protected/private Component field that holds one Component instance. | ||
− | + | ||
+ | ==Consequences== | ||
+ | * Decorator gives more flexibility than static inheritance because responsibilities can be added and removed at runtime. Decorator also makes it easy to add a single responsibility multiple times and combine responsibilities arbitrarily. | ||
+ | * Decorator avoids feature-laden classes high up in the class hierarchy, which happens if you use static inheritance instead. | ||
+ | * A decorated component is not identical to a non-decorated component. Thus you can't rely on object identity when using the Decorator pattern. | ||
+ | * Decorator can produce lots of little and very similar objects. These can be hard to learn and debug. | ||
+ | |||
+ | ==Related Patterns== | ||
+ | *[[Adapter]]: An [[Adapter]] gives an object a whole new interface, while a Decorator add extra functionality while keeping the object's original interface intact. | ||
+ | *[[Composite]]: A Decorator is often used together with the [[Composite]] pattern. Decorator adds additional responsibilities and is not intended for object aggregation like [[Composite]]. | ||
+ | *[[Strategy]]: Decorator and [[Strategy]] are two different ways of changing an object. A Decorator changes the skin of an object while a [[Strategy]] changes the internal workings of the object. | ||
==See also== | ==See also== | ||
+ | *[[Composite]] | ||
*[[Strategy]] | *[[Strategy]] | ||
+ | *[[Favor composition over inheritance]] | ||
+ | |||
+ | {{design patterns}} |
Latest revision as of 03:10, 25 November 2010
The Decorator pattern makes it possible to add new/additional behavior/functionality to an existing class dynamically. This works by adding a decorator class, which has the same interface as the original (decorated) class. The decorator class wraps the original class which is usually achieved by passing the original object as a parameter to the constructor of the decorator when it is created.
The decorator pattern is an alternative to subclassing (see Strategy). While subclasssing adds behaviour at compile time, the decorator pattern can provide new funtionality at runtime.
Contents |
Typical Usage
- to add functionality to individual objects dynamically and transparently, that is, without affecting other objects.
- for behaviour 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.
Example
A nice example is a webbrowser. A webbrowser is viewing webpages. The webpage itself displays the information and the webbrowser knows nothing about the content of the webpage. So it is possible that the webpage doesn't fit into the webbrowsers window. Therefore windowscrollbars are needed to show the information. However the browser shouldn't assume that scrollbars are always required and certainly it should never assume scrollbars are not needed at all. So scrollbars are just displayed when really required. Thus in this case the decorator adds dynamically scrollbars to the window of the webpage whenever they are needed.
- You can find here a nicely explained example of the Decorator Pattern usage in the real world along with java code.
UML-Diagram
Participating Classes
Component
Window
Defines the abstract interface of the decorated object which can have added funtionality dynamically.
ConcreteComponent
SimpleWindow
Defines an object to which additional behaviour can be attached.
Decorator
WindowDecorator
Maintains a reference to the Component and defines a interface which complies to the Components interface.
ConcreteDecorator
HorizontalScrollbarDecorator,VerticalScrollbarDecorator
Adds new functionality to the Component
Recognising the pattern
Classes: Component, ConcreteComponent, Decorator, ConcreteDecorator
- Inheritance hierarchy that has a Component interface.
- Decorator class has protected/private Component field that holds one Component instance.
Consequences
- Decorator gives more flexibility than static inheritance because responsibilities can be added and removed at runtime. Decorator also makes it easy to add a single responsibility multiple times and combine responsibilities arbitrarily.
- Decorator avoids feature-laden classes high up in the class hierarchy, which happens if you use static inheritance instead.
- A decorated component is not identical to a non-decorated component. Thus you can't rely on object identity when using the Decorator pattern.
- Decorator can produce lots of little and very similar objects. These can be hard to learn and debug.
Related Patterns
- Adapter: An Adapter gives an object a whole new interface, while a Decorator add extra functionality while keeping the object's original interface intact.
- Composite: A Decorator is often used together with the Composite pattern. Decorator adds additional responsibilities and is not intended for object aggregation like Composite.
- Strategy: Decorator and Strategy are two different ways of changing an object. A Decorator changes the skin of an object while a Strategy changes the internal workings of the object.
See also
Design patterns | |
---|---|
Creational: Abstract Factory | Builder | Factory Method | Prototype | Singleton |