Design Patterns Simplified - Part Twelve (Composite)

I am here to continue the discussion around Design Patterns. Today, we will go through one of the structural design patterns called Composite.

Also in case you have not had a look at our previous articles, go through the following link:

Before talking about its implementation let’s begin with defining it.

As per GOF guys, Composite pattern is defined as in the following.

“Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.”

Well! Let’s understand what they mean and where this pattern can be fit into.

In cases when data is available in hierarchical format and both individual (leaf) and composite (non-leaf) objects are treated in the same way, composite pattern turns out to be the perfect fit.

For example, employee structure in an organization where leadership or CEO stands in the top followed by bunch of directors and managers and then the junior employees.

diagram

In this case CEO, Directors, and Managers are composite objects as they manage their subordinates, however, Employees or Junior Employees are the individual objects that appear in the leaf of the structure.

Another example could be file system structure in a computer where hierarchy can be formed right from root folder until the last file available.

Child controls in the Windows or Web forms can also be handled by Composite pattern as they also follow the below given hierarchy.
  • Form -> Panel ->TextBox
  • Form -> Panel ->Table ->TextBox
  • Form -> Table-> Label

Below is the UML of Composite pattern.

pattern

Composite pattern has three key elements as following.

  • Component: This is the abstract class or interface containing methods that will be implemented by all the objects in the hierarchy.
  • Composite: This class keeps all the methods required to manage its child objects i.e. Add/Remove/Get and common method defined in Component.
  • Leaf: This class has only the common method defined in Component.

How Composite pattern works?

We will understand this by simple example.

Let’s start with creating Component which is the base for all the objects

  1. ///<summary>  
  2. /// The Component  
  3. ///</summary>  
  4. public interface IEmployee   
  5. {  
  6.     void ShowYearsOfExperiance();  
  7. }  
In the above interface, we have declared ShowYearsOfExperience as it's common to all the employees be  itthe CEO, manager, or junior.

Now we will create the Manager class which will be the composite class.
  1. ///<summary>  
  2. /// The Composite  
  3. ///</summary>  
  4. public class Manager: IEmployee  
  5. {  
  6.     private string _empName  
  7.     {  
  8.         get;  
  9.         set;  
  10.     }  
  11.     private float _yearsOfExperiance  
  12.     {  
  13.         get;  
  14.         set;  
  15.     }  
  16.     private List < IEmployee > subordinates = newList < IEmployee > ();  
  17.     public Manager(stringempName, floatyearsOfExperiance)  
  18.     {  
  19.         this._empName = empName;  
  20.         this._yearsOfExperiance = yearsOfExperiance;  
  21.     }  
  22.     public void ShowYearsOfExperiance()  
  23.     {  
  24.         Console.WriteLine("Manager {0} has {1} number of years of experiance", _empName, _yearsOfExperiance);  
  25.         foreach(IEmployeeempin subordinates)  
  26.         {  
  27.             emp.ShowYearsOfExperiance();  
  28.         }  
  29.     }  
  30.     public void AddSubordinate(IEmployeeemp)  
  31.     {  
  32.         subordinates.Add(emp);  
  33.     }  
  34.     public void RemoveSubordinate(IEmployeeemp)  
  35.     {  
  36.         subordinates.Remove(emp);  
  37.     }  
  38. }  
The above composite class hasa  set of methods to handle operations related to subordinates apart from implementing common method (ShowYearsOfExperiance) defined in IEmployee.

Now the time has come to create Leaf object class which will cater to junior employees.
  1. ///<summary>  
  2. /// The Leaf  
  3. ///</summary>  
  4. public class Junior Employee: IEmployee   
  5. {  
  6.     private string _empName   
  7.     {  
  8.         get;  
  9.         set;  
  10.     }  
  11.     private float _yearsOfExperiance {  
  12.         get;  
  13.         set;  
  14.     }  
  15.     public JuniorEmployee(stringempName, floatyearsOfExperiance)   
  16.     {  
  17.         this._empName = empName;  
  18.         this._yearsOfExperiance = yearsOfExperiance;  
  19.     }  
  20.     public void ShowYearsOfExperiance()   
  21.     {  
  22.         Console.WriteLine("\tSubordinate {0} has {1} number of years of experiance", _empName, _yearsOfExperiance);  
  23.     }  
  24. }  
So at this point, we are done with creating key components (Component/Composite/Leaf), now let’s see how client uses them.
  1. Console.Title = "Composite pattern demo";  
  2. Console.Title = "Composite pattern demo";  
  3. //Create JuniorEmployee object  
  4. JuniorEmployeejEmp1 = newJuniorEmployee("Ramesh", 2);  
  5. JuniorEmployeejEmp2 = newJuniorEmployee("Suresh", 3);  
  6. JuniorEmployeejEmp3 = newJuniorEmployee("Manoj", 2.5 f);  
  7. //Create Manager object  
  8. Managermanager1 = newManager("Prakash", 8);  
  9. Managermanager2 = newManager("Pankaj", 8.5 f);  
  10. Console.WriteLine("Adding Subordinates...");  
  11. //Add Subordinate  
  12. manager1.AddSubordinate(jEmp1);  
  13. manager1.AddSubordinate(jEmp2);  
  14. manager2.AddSubordinate(jEmp3);  
  15. //Call the common method which will execute in hierarchical fashion.  
  16. manager1.ShowYearsOfExperiance();  
  17. manager2.ShowYearsOfExperiance();  
  18. Console.WriteLine("\nRemoving Subordinates...");  
  19. //Remove Subordinate  
  20. manager1.RemoveSubordinate(jEmp2);  
  21. manager2.RemoveSubordinate(jEmp3);  
  22. //Call the common method after removal  
  23. manager1.ShowYearsOfExperiance();  
Output:

output
You can see in the above output how employee’s structure is getting shown in the hierarchical fashion using composite pattern.

A point to be noted here that Composite pattern assumes that both composite (i.e. Manager) and individual (JuniorEmployee) objects are used and accessed in similar way, this is the reason we extracted common behavior (YearsOfExperiance) and put in the Component (IComponent).

To summarize, composite pattern can be used in cases where hierarchical representation of objects are required and both individual and composite objects are treated in the same way.

Hope you have liked the article. Look forward to your comments/ suggestions.
Read more articles on Design Patterns