Friday, September 5, 2008

Decorator Pattern

The formal definition of the Decorator pattern:
"Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality."

Decorator pattern is a structural pattern.
 It is easy to add functionality to an entire class of objects by subclassing an object, but it is impossible to extend a single object this way. With the Decorator Pattern, you can add functionality to a single object and leave others like it unmodified.



A decorator pattern is also known as Wrapper.The decorator pattern is an alternative to subclassing. Subclassing adds behaviour at compile time whereas decorating can provide new behaviour at runtime.This allows us to design flexible systems which are configurable by set up options or user selections.


The class to which we are going to add the new behaviour is called the Component, and the new behaviours are added by using various Decorators (Wrappers) to operate upon the Component. The Decorator is a new class that is added into the system. The Component class does not need to, and will not, be aware of it's existence.


Examples in the .Net Framework :One of the reasons I think design patterns are important is that they occur in other people's code we inherit and use. Recognizing the patterns in someone else's code can help you understand that code. Here's a handful of examples from the
Chaining IHttpModule classes in an ASP.NET application is an example of a decorator. Each IHttpModule in the interception chain adds behavior before it delegates to it's inner IHttpModule. Microsoft refers to this specific usage or a decorator as an
Intercepting Filter.
The XmlValidatingReader class adds schema validation to any type of XmlReader. Clients that depend on the XmlReader type never know the difference.
The System.IO.BufferedStream decorates any other kind of Stream to add buffering. By using a decorator pattern, the .Net team didn't need to create specific subclasses for "BufferedFileStream" or "BufferedMemoryStream." There is another Stream class that decorates other streams to provide transparent encryption.

Advantages of Decorator pattern :
1. The new behaviours can be selectively applied at run time, rather than statically at compile time. This allows us to design flexible systems which are configurable by set up options or user selections.
2. The new behaviours can be selectively applied to just specific instances rather across the whole class to all instances.
3. The pattern allows us to both add and withdraw behaviours. If a behaviour is added by a Decorator we can remove the behaviour by just detaching the Decorator.
4. The pattern allows us to design systems that operate on a "pay as you go" basis where overhead is only incurred when and if the Decorator is employed.
5. In a system maintenance situation we may be able to implement change with less risk by using the Decorator pattern. We are able to extend or change existing behaviours, or to add new behaviours, without the Programmer necessarily having access to the Component class.
6. In a situation where there are many different Component classes, all with the same interface, we would be forced to create an equal number of sub-classes if we were to use static inheritance to implement the new behaviours. The Decorator pattern may enable us to use just one Decorator to work with all of the component classes.

The Decorator pattern is only making changes to the Component from the outside. If more invasive changes are required it would be better to look to the Strategy pattern where the Component would outsource some of it's functionality to one of several Strategy classes.This pattern is useful for extending classes that are locked by use of the "sealed" keyword.

(diagram)

No comments: