Tag Archives: Decorator pattern

A Simple implementation for decorator pattern

For detailed explanation of decorator pattern, please check this link: https://alagesann.com/2013/08/16/decorator-pattern-made-easy/


public interface IPizza
 {
 int GetPrice();
 }

 public class Pizza : IPizza
 {
 public int GetPrice()
 {
 return 10;
 }
 }

 public class PizzaWithCheese : IPizza
 {
 private int CheesePrice { get; set; }
 private IPizza pizza;
 public PizzaWithCheese(IPizza pizza,int price)
 {
 this.pizza = pizza;
 CheesePrice = price;
 }
 public int GetPrice()
 {
 return pizza.GetPrice() + CheesePrice;
 }
 }

 public class PizzaWithChicken : IPizza
 {
 private int ChickenPrice { get; set; }
 private IPizza pizza;
 public PizzaWithChicken(IPizza pizza, int price)
 {
 this.pizza = pizza;
 ChickenPrice = price;
 }
 public int GetPrice()
 {
 return pizza.GetPrice() + ChickenPrice;
 }
 }

 class Program
 {
 static void Main(string[] args)
 {
 IPizza pizza = new Pizza();
 Console.WriteLine("Default pizza price=" + pizza.GetPrice());
 IPizza pizzaWithCheese = new PizzaWithCheese(pizza, 10);
 Console.WriteLine("pizza with cheese price=" + pizzaWithCheese.GetPrice());

IPizza pizzaWithChicken = new PizzaWithChicken(pizza, 20);
 Console.WriteLine("pizza with chicken price=" + pizzaWithChicken.GetPrice());

IPizza pizzaWithCheeseAndChicken = new PizzaWithChicken(pizzaWithCheese, 20);
 Console.WriteLine("pizza with cheese and chicken price=" + pizzaWithCheeseAndChicken.GetPrice());
 Console.ReadKey();
 }
 }

Sample output:


Default pizza price=10
pizza with cheese price=20
pizza with chicken price=30
pizza with cheese and chicken price=40

Advertisements

Decorator pattern made easy

Add new role or functionality dynamically to an object.

Real life Decorator in an organization:

Everybody from an organization is an employee, when he/she does not have a role/job title for a moment. Once he/she is assigned with a role he becomes responsible to do the functionality of the role he is assigned. Again, the role assigned to him is not permanent, business environment - teamwork graph  15mpbased on his performance he could be either promoted to a new position with new role or depromoted to his old position or he can stay with the same position. Often, there will be employees who will perform more than one role at the same time, for ex: A Manager will do team management and task assignment to his subordinates. How will it be if HR dept. doesn’t have capability to assign/reassign new roles and responsibilities to employees like I just said? Employee always will have only one permanent role for ever. You know that’s a bad HR dept. Assigning and reassigning roles, responsibilities or properties to an object is decorating, just like make-up, you act differently for the kind of make-up you put on.

Definition from GoF:

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

Problem domain:

Say, we are designing HR Application. Everybody as an employee can do basic functionalities such as Join, Termination and basic functionalities. So Employee is the basic component of the application. Based on the responsibilities each employee is assigned a different or more than one role to perform.  We should be able to assign/ remove any role (Engineer, team lead, manager etc.) to the employee dynamically. It should adhere to Open-Close principle i.e., creating and assigning new role should be easy without changing existing class hierarchy.

For now, following must be implemented.

I)                    An Engineer can do basic stuff and Coding.

II)                  A TeamLead can do basic stuff and task management.

III)                A manager can do basic stuff, task management and also people management.

Since the problem calls for dynamically adding/removing responsibilities to an object, it can be solved using decorator pattern.

Class diagram of HR application using decorator pattern:

HRApp_Classdiagram

Participant:

Component (IEmployee)
– Defines the interface for the objects that can have responsibilities added to them                     dynamically.
Concrete Component (Employee)
– Defines an object to which additional responsibilities can be added.
Decorator (Role)
– Maintains a reference to a component object and defines an interface that conforms to           component’s interface.
Concrete decorators (Engineer, TeamLead, Manager)
– Adds responsibilities to the component.

Implementation:
First, Component interface, this defines all the operations of an Employee along with Name.


public interface IEmployee
 {
 string Name { get; set; }
 string Join();
 string Terminate();
 string PerformJob();
 }

Now we will implement a one concrete Employee class, this is going to be the basic Concrete implementation of an employee to which responsibilities will be added dynamically. For now , it will do only basic functionalities.


public class Employee : IEmployee
 {
 public string Name { get; set; }
 public Employee(string Name)
 {
 this.Name = Name;
 }
public string Join()
 {
 return Name + " joined the company..";
 }

public string Terminate()
 {
 return Name + " left the company..";
 }
 public string PerformJob()
 {
 return Name + " doing basic stuff..";
 }

}

Now we will define an abstract class (interface) which will have an object for the component interface to delegate to perform the basic operations. Also this will help avoid the concrete decorator to implement all operations that are already available in employee component class that are going to be common for all the employee roles. These basic /common operations will be inherited to the concrete decorators.


public abstract class Role: IEmployee
 {
 public abstract IEmployee Employee { get; set; }

public string Name { get ; set; }

public string Join()
 {
 return Employee.Join();
 }

public string Terminate()
 {
 return Employee.Terminate();
 }
 public abstract string PerformJob();
 }

Engineer class implementation:


public class Engineer : Role
 {
 public override IEmployee Employee { get; set; }
 public Engineer(IEmployee Employee)
 {
 this.Employee = Employee;
 }
 public override string PerformJob()
 {
 return Employee.PerformJob() + " and Coding";
 }
 }

Team Lead class implementation:


public class TeamLead : Role
 {
 public override IEmployee Employee { get; set; }
 public TeamLead(IEmployee Employee)
 {
 this.Employee = Employee;
 }
 public override string PerformJob()
 {
 return Employee.PerformJob() + " and Task Management";
 }
 }

Manager class implementation:


public class Manager : Role
 {
 public override IEmployee Employee { get; set; }
 public Manager(IEmployee Employee)
 {
 this.Employee = Employee;
 }
 public override string PerformJob()
 {
 return Employee.PerformJob() + " and People management";
 }
 }

Client program:


class Program
 {
 static void Main(string[] args)
 {
 IEmployee employee1 = new Employee("George");
 IEmployee employee2 = new Employee("John");
 IEmployee employee3 = new Employee("Thomas");
 Console.WriteLine(employee1.Join());
 Console.WriteLine(employee2.Join());
 Console.WriteLine(employee3.Join());
 Engineer engineer = new Engineer(employee1);
 Console.WriteLine(engineer.PerformJob());
 TeamLead lead = new TeamLead(employee2);
 Console.WriteLine(lead.PerformJob());
 Manager manager = new Manager(new TeamLead(employee3));
 Console.WriteLine(manager.PerformJob());
 Console.WriteLine(engineer.Terminate());
 Console.WriteLine(lead.Terminate());
 Console.WriteLine(manager.Terminate());
 Console.ReadKey();
 }
 }

Sample output:

 George joined the company..
 John joined the company..
 Thomas joined the company..
 George doing basic stuff.. and Coding
 John doing basic stuff.. and Task Management
 Thomas doing basic stuff.. and Task Management and People management
 George left the company..
 John left the company..
 Thomas left the company..

As you can see, we can now dynamically create any role at run time and assign it to the default employee object. It’s so flexible than inheritance where you cannot add responsibilities dynamically, everything is static there. Decorator pattern is otherwise called as Wrapper as each decorator wraps a component inside it to which it delegates the functionalities. Decorator pattern is structural pattern.

For a simple implementation of decorator pattern, please check this link: https://alagesann.com/2013/08/16/a-simple-implementation-for-decorator-pattern/