In this article You will learn how to implement decorator pattern in C#. Decorator pattern allows to modify an object dynamically it simplifies the code by adding new functionality at runtime. Adding new functionality to the object doesn’t effect the initial class structure.
In my example I’ll simulate the process of enchanting an item in RPG game.
UML Diagram:
Component
This interface will be used as base for decorator and concrete items. It contains methods that will return properties of an item.
public interface IItem
{
string GetName();
int GetValue();
}
Base Items like armor or Sword will implement this interface, And return fixed values.
class Sword : IItem
{
public string GetName()
{
return "Iron Sword";
}
public int GetValue()
{
return 20;
}
}
Decorator
This is the key part of the pattern, it maintains a reference to a Component object and defines an interface that conforms to Component’s interface. In my example this will be represented as an Enchantment of the item. Decorater will have form of abstract class and will have protected constructor
A protected member is accessible within its class and by derived class instances.
abstract class Enchantment : IItem
{
IItem _item = null;
protected int _Value = 0;
protected Enchantment(IItem baseItem)
{
_item = baseItem;
}
public string GetName()
{
return (_item.GetName() +" +1 ");
}
public int GetValue()
{
return (_item.GetValue() + _Value);
}
}
Class that extends the Decorator can change the protected vales in parent to eventually change the return values.
class Magic : Enchantment
{
public Magic(IItem baseComponent): base(baseComponent)
{
this._Value = 30;
}
}
Client
Last part of an application. Here the instance of an item is created and modified. In this example you can see how the values changed after adding decorator.
class Program
{
static void Main(string[] args)
{
IItem newItem = new Sword();
Console.WriteLine(newItem.GetName() + " Value: " + newItem.GetValue().ToString());
newItem = new Magic(newItem);
Console.WriteLine(newItem.GetName() + " Value: " + newItem.GetValue().ToString());
Console.ReadLine();
}
}
To conclude, Decorator can attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub-classing for extending functionality. I hope that this was understandable and it will help you with your projects. This was probably the last design pattern to cover on my blog, last in this month at least. Stay Awesome!