The role of the Decorator pattern is to provide a way of attaching new state and behavior to an object dynamically. As its name suggests, the Decorator pattern takes an existing object and adds to it, consider a photo that is displayed on a screen.There are many ways to add to the photo, such as putting a border around it or specifying tags related to the content. Such additions can be displayed on top of the photo, The combination of the original photo and some new content forms a new object.
we can specify the players in the Decorator pattern in a UML diagram:
Component : An original class of objects that can have operations added or modified(there may be more than one such class)
Operation :An operation in IComponent objects that can be replaced(there may be several
operations)
Icomponent :The interface that identifies the classes of objects that can be decorated(Component is one of these)
Decorator :A class that conforms to the IComponent interface and adds state and/or behavior(there may be more than one such class)
The center of the UML diagram is the Decorator class. It includes two types of relationships with the IComponent interface:
Is-a
The is-a relationshipis shown by a dotted arrow from the Decorator to IComponent, indicating that Decorator realizes the IComponent interface. The fact that Decorator inherits from
IComponent means that Decorator objects can be used wherever IComponent objects are expected. The Component class is also in an is-a relationship with IComponent, and therefore the client can use Component and Decorator objects interchangeably—the heart of the Decorator pattern.
Has-a
The has-a relationshipis shown by an open diamond on the Decorator, linked to IComponent. This indicates that the Decorator instantiates one or more IComponent objects and that decorated objects can outlive the originals. The Decorator uses the component attribute (of type IComponent) to invoke any replacement Operation it might wish to override. This is the way the Decorator pattern achieves its objective.The addedBehavior operation and the addedState attribute in the Decorator class are other optional ways of extending what is in the original Component objects. And this the implementaion :
using System;
///
<summary>
/// Summary description for Decorator
///
</summary>
///
class DecoratorPattern
{
// Decorator Pattern Judith Bishop Dec 2006
// Shows two decorators and the output of various
// combinations of the decorators on the basic component
interface IComponent
{
string Operation();
}
class Component:IComponent
{
public string Operation()
{
return "I am walking ";
}
}
class DecoratorA :IComponent {
IComponent component;
public DecoratorA(IComponent c)
{
component = c;
}
public string Operation()
{
string s=component.Operation();
s += "and listening to Classic FM ";
return s;
}
}
class DecoratorB : IComponent {
IComponent component;
public string addedState = "past the Coffee Shop ";
public DecoratorB(IComponent c)
{
component = c;
}
public string Operation()
{
string s =component.Operation();
s += "to school ";
return s;
}
public string AddedBehavior()
{
return "and I bought a cappuccino ";
}
}
class Client
{
static void Display(string s, IComponent c)
{
Console.WriteLine(s + c.Operation());
}
static void Main( ) {
Console.WriteLine("Decorator Pattern\n");
IComponent component = new Component( );
Display("1. Basic component: ", component);
Display("2. A decorated : ", new DecoratorA(component));
Display("3. B-decorated : ", new DecoratorB(component)); Display("4. B-A-decorated : ", new
DecoratorB(new Decorator(component)));
// Explicit DecoratorB
DecoratorB b = new DecoratorB(new Component( ));
Display("5. A-B decorated : ", new DecoratorA(b));
// Invoking its added state and added behavior
Console.WriteLine("\t\t\t"+b.addedState + b.AddedBehavior( ));
}
}
}
/* Output
Decorator Pattern
1. Basic component: I am walking
2. A-decorated : I am walking and listening to Classic FM
3. B-decorated : I am walking to school
4. B-A-decorated : I am walking and listening to Classic FM to school
5. A-B-decorated : I am walking to school and listening to Classic FM past the Coffee Shop and I bought a cappuccino
*/
The example starts off with the IComponent interface and a simple Component class that implements it . There are two decorators that also implement the interface; each of them includes a declaration of an IComponent, which is the object it will decorate. DecoratorA is fairly plain and simply implements the Operation by calling it on the component it has stored, then adding something to the string it returns . DecoratorB is more elaborate. It also implements
the Operation in its own way, but it offers some public addedState and addedBehavior as well. In both implemented operations, the component's Operation method is called first, but this is not a requirement of the pattern;it merely makes for more readable output in this example.The Client class is responsible for creating components and decorators in various configurations and displaying the result of calling the Operation in each case. decorate the basic component in different ways.
Best Wishes