Decorator In C#

Decorator design 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 lesson, we will learn,
  • Decorator Design Pattern
  • Implementation Guidelines
  • Sample Implementation

Decorator Design Pattern

 
 
“Attach additional responsibilities to an object dynamically. Decorator provides a flexible alternative to sub classing for extending functionality”.
  • Decorator falls under the category of Structural Design pattern and is also knows as Wrapper.
  • Decorator design pattern follows the Open Closed Principle, one of the SOLID principles.
  • In other words, it helps to add new responsibilities to an individual instance of an object, without adding those responsibilities to the class of objects. Decorator can be thought of as an alternative to inheritance.
Implementation Guidelines
  • Need to add responsibilities to individual objects dynamically and transparently.
  • The extension by subclassing is impractical.
  • Class definition may be hidden
  • Classes are unavailable for subclassing

Decorator Pattern representation

 
The participants in a typical implementation of the Decorator design pattern include,
  1. Component
    This represents the base type of the actual or the concrete type

  2. Concrete Component
    This represents the concrete type that extends the base component. Note that the additional responsibilities or functionalities are added in this type.

  3. Decorator
    This represents a reference to a component. The dynamic functionalities are added in this type.

  4. ConcreteDecorator
    Objects are the classes which actually add responsibilities to the ConcreteComponent classes.
Sample Implementation
 
The classes, interfaces, and objects which we are going to use in sample implementation are identified as follows:
  1. Employee: Component class
  2. EmployeeConcrete: Concrete Component 
  3. EmployeeDecorator: Decorator Class 
  4. PermanentEmployeeDecorator: Concrete Decorate Class 
  5. ContractEmployeeDecorator: Concrete Decorate class
Employee Class
  1. public abstract class Employee {  
  2.     public abstract string Display();  
  3.  
Note
  1. It doesn’t necessarily mean that you have to use abstract type.- the type may or may not be abstract.
  2. You can also implement a decorator design pattern using interface. 
  3. You can use methods that are virtual in your concrete classes. 
We are using abstract type here for the sake of simplicity.
 
EmployeeConcrete Class extends Employee class and adds additional properties
  1. public class EmployeeConcrete: Employee {  
  2.     public string FirstName {  
  3.         set;  
  4.         get;  
  5.     }  
  6.     public string LastName {  
  7.         set;  
  8.         get;  
  9.     }  
  10.     public string Address {  
  11.         set;  
  12.         get;  
  13.     }  
  14.     public override string Display() {  
  15.         StringBuilder data = new StringBuilder();  
  16.         data.Append("First name: " + FirstName);  
  17.         data.Append("\nLast name: " + LastName);  
  18.         data.Append("\nAddress: " + Address);  
  19.         return data.ToString();  
  20.     }  
  21. }  
The EmployeeDecorator class extends the Employee class, accepts an instance of the component class named Employee, and overrides the Display() method.
  1. public class EmployeeDecorator: Employee {  
  2.     Employee _employee = null;  
  3.     public EmployeeDecorator(Employee employee) {  
  4.         this._employee = employee;  
  5.     }  
  6.     public override string Display() {  
  7.         return _employee.Display();  
  8.     }  
  9. }  
Now the Component, Concrete Component and the decorator classes are ready. Now, we can extend the EmployeeDecorator class to create concrete decorator classes.
 
PermanentEmployeeDecorator class
  1. public class PermanentEmployeeDecorator: EmployeeDecorator {  
  2.     //Add properties relevant to a permanent employee  
  3.     private double PF {  
  4.         get;  
  5.         set;  
  6.     }  
  7.     public PermanentEmployeeDecorator(Employee employee): base(employee) {}  
  8.     public override string Display() {  
  9.         return base.Display() + "\nEmployee type: Permanent";  
  10.     }  
  11. }  
Assume that you can also have another type of employee -- a contractual employee. To represent it, you would need to create another class named ContractEmployeeDecorator that extends the EmployeeDecorator class.
  1. public class ContractEmployeeDecorator: EmployeeDecorator {  
  2.     //Add properties relevant to a contract employee  
  3.     private double RatePerHour {  
  4.         get;  
  5.         set;  
  6.     }  
  7.     public ContractEmployeeDecorator(Employee employee): base(employee) {}  
  8.     public override string Display() {  
  9.         return base.Display() + "\nEmployee type: Contractual";  
  10.     }  
  11. }  
Now, you can now create an instance of PermanentEmployeeDecorator and ContractEmployeeDecorator and use it as shown below.
  1. class Program {  
  2.     static void Main(string[] args) {  
  3.         var permanentemployeeConcrete = new EmployeeConcrete {  
  4.             FirstName = "Prasad",  
  5.                 LastName = "Raveendran",  
  6.                 Address = "Isline, US"  
  7.         };  
  8.         var employeeDecorator = new PermanentEmployeeDecorator(permanentemployeeConcrete);  
  9.         Console.WriteLine(employeeDecorator.Display());  
  10.         var contractemployeeConcrete = new EmployeeConcrete {  
  11.             FirstName = "Praveen",  
  12.                 LastName = "Raveendran",  
  13.                 Address = "Houston, US"  
  14.         };  
  15.         var conemployeeDecorator = new ContractEmployeeDecorator(contractemployeeConcrete);  
  16.         Console.WriteLine(conemployeeDecorator.Display());  
  17.         Console.Read();  
  18.     }  
  19. }  
We saw a brief formal introduction of the Decorator Pattern and then we had a look at a concrete problem that this construct is a natural fit for. Another example could have been a pizza shop or a car or bike configurator. Anything that deals with objects whose behaviors should be extendable dynamically would do.
 
I haven't personally used it outside of demos, but I can see it being useful in many circumstances. I'm also wondering if maybe ASP.NET MVC's “attributes” consider as the usage of the Decorator pattern, but I'm not sure (so if anyone can clear this up for me, it would be much appreciated).
 

Summary

 
The Decorator pattern seeks to dynamically add functionality to instances of objects at runtime, without needing to change the definition of the instance's class. This is especially useful in scenarios where different instances of the same object might behave differently
I hope you will enjoy the decorator Pattern while designing your software. Your valuable feedback or comments about this article are always welcome.


Similar Articles