Pages

Wednesday, March 28, 2012

Design Pattern Tutorial Part 2: The Decorator Pattern (Structural Pattern) : Example in C#.net

Part 1

Here is an example of the implementation of the Decorator Pattern with C#.net.


   1:      class Program
   2:      {
   3:          static void Main(string[] args)
   4:          {
   5:              IComponent component = new Component();
   6:              Output("Original component: ", component);
   7:              Output("Decorated by A : ", new DecoratorA(component));
   8:              Output("Decorated by B: ", new DecoratorB(component));
   9:              Output("Decorated by A then by B: ", new DecoratorB(new DecoratorA(component)));
  10:              
  11:              DecoratorB b = new DecoratorB(new Component());
  12:              Output("Decorated by B then by A: ", new DecoratorA(b));
  13:              
  14:              // Extended behavior
  15:              Console.WriteLine("\t\t\t\t\t\t" + b.ExtendedBehaviour());
  16:   
  17:              Console.ReadKey();
  18:          }
  19:   
  20:          static void Output(string s, IComponent component)
  21:          {
  22:              Console.WriteLine(s + component.Operation());
  23:          }
  24:      }
  25:   
  26:      public interface IComponent
  27:      {
  28:          string Operation();
  29:      }
  30:   
  31:      public class Component : IComponent
  32:      {
  33:          private string firstName = "Debashish";
  34:          private string lastName = "Shiman";
  35:   
  36:          public string Operation()
  37:          {
  38:              return firstName + " " + lastName;
  39:          }
  40:      }
  41:   
  42:      public class DecoratorA : IComponent
  43:      {
  44:          IComponent component;
  45:   
  46:          public DecoratorA(IComponent c)
  47:          {
  48:              component = c;
  49:          }
  50:   
  51:          public string Operation()
  52:          {
  53:              string s = component.Operation();
  54:              s = "Mr " + s;
  55:              return s;
  56:          }
  57:      }
  58:   
  59:      public class DecoratorB : IComponent
  60:      {
  61:          IComponent component;
  62:   
  63:          public DecoratorB(IComponent c)
  64:          {
  65:              component = c;
  66:          }
  67:   
  68:          public string Operation()
  69:          {
  70:              string s = component.Operation();
  71:              s = s + ", Software Engineer";
  72:              return s;
  73:          }
  74:   
  75:          public string ExtendedBehaviour()
  76:          {
  77:              return " and Web Developer";
  78:          }
  79:      }

Design Pattern Tutorial Part 1: The Decorator Pattern (Structural Pattern)

The Decorator Pattern is used to extend the functionality of a particular object in runtime without changing the object hence without affecting the other instance of the same class. The object is said to be “decorated” with new extended functionality. This is achieved by creating a new wrapper or “decorator” class which wraps the original class. 

 

Features

One of the key features of the Decorator Pattern, from the point of implementation, is that a decorator class both inherits the original class and contains an instance of it. The other features are:
  • The original object remains unaffected by the decoration and so does the other instances.
  • No one class becomes burdened with lots of features making the objects light-weight.
  • The decorations are independent from each other, so that hundreds of decorators can be there to provide thousands of decoration combinations.

 

Uses

The Decorator pattern may be useful in following situations:
  • For evolving systems where there are frequent changes in functionality.
  • To attach new functionality or behaviour to an object.
  • To Change the behaviour of an object without affecting other instances.
  • Avoid subclassing as too many classes could result.
  • Where there is a component class unavailable for subclassing.

 

Design

 

  • IComponent: The interface that identifies the classes of objects that can be decorated.
  • Decorator: The class that both implements the “IComponent” interface and has an instance of it. It is possible to have more than one classes of this kind.
  • Component: The original class which can be decorated by extended behaviours.
  • DecoratorA & DecoratorB: Extended classes of “Decorator” for further extension.