Decorator Pattern

Decorator pattern falls under Structural Pattern of Gang of Four (GOF) Design Patterns in .Net. Decorator pattern is used to add new functionality to an existing object without changing its structure. Hence Decorator pattern provides an alternative way to inheritance for modifying the behavior of an object. In this article, I would like to go over what the decorator pattern can do, and how it works.

There are some occasions in our applications when we need to create an object with some basic functionality in such a way that some extra functionality can be added to this object dynamically. For example, Lets say we need to create a Stream object to handle some data but in some cases we need this stream object to be able to encrypt the stream in some cases. So what we can do is that we can have the basic Stream object ready and then dynamically add the encryption functionality when it is needed.

One may also say that why not keep this encryption logic in the stream class itself and turn it on or off by using a Boolean property. But this approach will have problems like – How can we add the type custom encryption logic inside a class? Now this can be done easily by subclassing the existing class and have custom encryption logic in the derived class.

This is a valid solution but only when this encryption is the only functionality needed with this class. But what if there are multiple functionalities that could be added dynamically to this class and also the combination of functionalities too. If we use the subclassing approach then we will end up with derievd classes equal to the number of combination we could have for all our functionalities and the actual object.

This is exactly the scenario where the decorator patter can be useful.  Decorators provide a flexible alternative to subclassing for extending functionality.”

Before looking into the details of decorator pattern let us go ahead, let’s have a look at what this pattern is and then see the class diagram of this pattern and see what each class is responsible for.

What is Decorator Pattern

Decorator pattern is used to add new functionality to an existing object without changing its structure.

This pattern creates a decorator class which wraps the original class and add new behaviors/operations to an object at run-time.

Still none the wiser?  Let’s look at a diagram to help you picture the pattern.

Decorator Pattern – UML Diagram & Implementation

The UML class diagram for the implementation of the decorator design pattern is given below:

The classes, interfaces and objects in the above UML class diagram are as follows:

Component

This is an interface containing members that will be implemented by ConcreteClass and Decorator.

ConcreteComponent

This is a class which implements the Component interface.

Decorator

This is an abstract class which implements the Component interface and contains the reference to a Component instance. This class also acts as base class for all decorators for components.

ConcreteDecorator

This is a class which inherits from Decorator class and provides a decorator for components.

C# – Implementation Code

public interface Component
{
 void Operation();
}
 
public class ConcreteComponent : Component
{
 public void Operation()
 {
 Console.WriteLine("Component Operation");
 }
}
 
public abstract class Decorator : Component
{
 private Component _component;
 
 public Decorator(Component component)
 {
 _component = component;
 }
 
 public virtual void Operation()
 {
 _component.Operation();
 }
}
 
public class ConcreteDecorator : Decorator
{
 public ConcreteDecorator(Component component) : base(component) { }
 
 public override void Operation()
 {
 base.Operation();
 Console.WriteLine("Override Decorator Operation");
 }
}

Decorator Pattern – Example

Who is what?

The classes, interfaces and objects in the above class diagram can be identified as follows:

  • Vehicle – Component Interface.
  • HondaCity- ConcreteComponent class.
  • VehicleDecorator- Decorator Class.
  • Special Offer- ConcreteDecorator class.

C# – Sample Code

/// <summary>
/// The 'Component' interface
/// </summary>
public interface Vehicle
{
 string Make { get; }
 string Model { get; }
 double Price { get; }
}
 
/// <summary>
/// The 'ConcreteComponent' class
/// </summary>
public class HondaCity : Vehicle
{
 public string Make
 {
 get { return "HondaCity"; }
 }
 
 public string Model
 {
 get { return "CNG"; }
 }
 
 public double Price
 {
 get { return 1000000; }
 }
}
 
/// <summary>
/// The 'Decorator' abstract class
/// </summary>
public abstract class VehicleDecorator : Vehicle
{
 private Vehicle _vehicle;
 
 public VehicleDecorator(Vehicle vehicle)
 {
 _vehicle = vehicle;
 }
 
 public string Make
 {
 get { return _vehicle.Make; }
 }
 
 public string Model
 {
 get { return _vehicle.Model; }
 }
 
 public double Price
 {
 get { return _vehicle.Price; }
 }
 
}
 
/// <summary>
/// The 'ConcreteDecorator' class
/// </summary>
public class SpecialOffer : VehicleDecorator
{
 public SpecialOffer(Vehicle vehicle) : base(vehicle) { }
 
 public int DiscountPercentage { get; set; }
 public string Offer { get; set; }
 
 public new double Price
 {
 get
 {
 double price = base.Price;
 int percentage = 100 - DiscountPercentage;
 return Math.Round((price * percentage) / 100, 2);
 }
 }
 
}
 
/// <summary>
/// Decorator Pattern Demo
/// </summary>
class Program
{
 static void Main(string[] args)
 {
 // Basic vehicle
 HondaCity car = new HondaCity();
 
 Console.WriteLine("Honda City base price are : {0}", car.Price);
 
 // Special offer
 SpecialOffer offer = new SpecialOffer(car);
 offer.DiscountPercentage = 25;
 offer.Offer = "25 % discount";
 
 Console.WriteLine("{1} @ Diwali Special Offer and price are : {0} ", offer.Price, offer.Offer);
 
 Console.ReadKey();
 
 }
}

Decorator Pattern Demo – Output

When to use it?

Add additional state or behavior to an object dynamically.

Make changes to some objects in a class without affecting others.

Original Article by Shailendra Chauhan

Here is a sample application Decorator Pattern

Factory Support Facility

Factory Support Facility allows using factories to create components. This is beneficial when you want to make available as services components that do not have accessible constructor, or that you don’t instantiate, like HttpContext.

Prefer UsingFactoryMethod over this facility: while the facility provides programmatic API it is deprecated and its usage is discouraged and won’t be discussed here. Recommended approach is to use UsingFactoryMethod method of fluent registration API to create components. This limits the usefulness of the facility to XML-driven and legacy scenarios.

UsingFactoryMethod does not require this facility anymore: In older versions of Windsor (up to and including version 2.1) UsingFactoryMethod method in the fluent API discussed above required this facility to be active in the container. That was later changed and there’s no such dependency anymore.

Using factories from configuration

In addition to code, the facility uses XML configuration. You can register the facility in the standard facilities section of Windsor’s config:

Just install the facility and add the proper configuration.

<configuration>
 <facilities>
   <facility
     id="factory.support"
     type="Castle.Facilities.FactorySupport.FactorySupportFacility, 
           Castle.Facilities.FactorySupport" />
  </facilities>
</configuration>

Configuration Schema

Broadly speaking facility exposes the following scheme, with two kinds of supported factories: accessors and methods

<components>
 <component id="mycomp1" instance-accessor="Static accessor name" />
 <component id="factory1" />
 <component id="mycomp2" factoryId="factory1" factoryCreate="Create" />
</components>

Accessor example

Given the following singleton class:

public class SingletonWithAccessor
{
 private static readonly SingletonWithAccessor instance = new SingletonWithAccessor();

private SingletonWithAccessor()
 {
 }

public static SingletonWithAccessor Instance
 {
 get { return instance; }
 }
}

You may expose its instance to the container through the following configuration:

<components>
 <component id="mycomp1"
 type="Company.Components.SingletonWithAccessor, Company.Components"
 instance-accessor="Instance" />
</components>

Using it:

var comp = container.Resolve<SingletonWithAccessor>("mycomp1");

Factory example

Given the following component and factory classes:

public class MyComp
{
 internal MyComp()
 {
 }

...
}

public class MyCompFactory
{
 public MyComp Create()
 {
 return new MyComp();
 }
}

You may expose its instance to the container through the following configuration:

<components>
 <component id="mycompfactory"
 type="Company.Components.MyCompFactory, Company.Components"/>
 <component id="mycomp"
 type="Company.Components.MyComp, Company.Components"
 factoryId="mycompfactory" factoryCreate="Create" />
</components>

Using it:

var comp = container.Resolve<MyComp>("mycomp");

Factory with parameters example

Given the following component and factory classes:

public class MyComp
{
 internal MyComp(String storeName, IDictionary props)
 {
 }

...
}

public class MyCompFactory
{
 public MyComp Create(String storeName, IDictionary props)
 {
 return new MyComp(storeName, props);
 }
}

You may expose its instance to the container through the following configuration:

<components>
 <component id="mycompfactory"
 type="Company.Components.MyCompFactory, Company.Components"/>
 <component id="mycomp"
 type="Company.Components.MyComp, Company.Components"
 factoryId="mycompfactory" factoryCreate="Create">
 <parameters>
 <storeName>MyStore</storeName>
 <props>
 <dictionary>
 <entry key="key1">item1</entry>
 <entry key="key2">item2</entry>
 </dictionary>
 </props>
 </parameters>
 </component>
</components>

Using it:

var comp = container.Resolve<MyComp>("mycomp");

Factory using auto-wire example

If your factory request as parameter some other component instance, this facility will be able to resolve it without your aid:

public class MyComp
{
 internal MyComp(IMyService serv)
 {
 }

...
}

public class MyCompFactory
{
 public MyComp Create(IMyService service)
 {
 return new MyComp(service);
 }
}

You may expose its instance to the container through the following configuration:

<facilities>
 <facility
 id="factorysupport"
 type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.Facilities.FactorySupport"/>
</facilities>

<components>
 <component id="myservice"
 service="SomethingElse.IMyService"
 type="Company.Components.MyServiceImpl, Company.Components" />
 <component id="mycompfactory"
 type="Company.Components.MyCompFactory, Company.Components" />
 <component id="mycomp"
 type="Company.Components.MyComp, Company.Components"
 factoryId="mycompfactory" factoryCreate="Create" />
</components>

Using it:

var comp = container.Resolve<MyComp>("mycomp");