Design Pattern For Beginner: Part 5: Composite Design Pattern

Welcome to the Design Patterns for Beginners article aeries. In this article we will be learning how to implement a Composite Design Pattern in applications. From the past few articles I have been discussing various design patterns. If you are rely passionate about learning design pattern then please visit my previous articles:

In today's session we will learn about the Composite Design Pattern and we will discuss a few scenarios where the Composite Design Pattern may rescue you. At first we will discuss why the Composite Design Pattern is needed.

What the Composite Design Pattern Is

The Composite Design Pattern always forms a tree structure with the objects, where each root element contains sub nodes called child nodes and child nodes contain leaf nodes (last label node). Leaf nodes do not contain any elements. Now, in this object hierarchy we can point any node and from this node we can traverse all other nodes.

For example, think about an employee stricture of an organization. We can easily represent it by a tree structure and if we start from the CEO (the root of the organization) then we can reach leaf employees by traversing through the middle-level managers.

Take another example of a Composite Design Pattern. Think about the folder structure of your computer. Each drive contains many folders and each folder contains many subfolders and each subfolder contains many files. Here the files are nothing but the leaf nodes. A node from any drive partition you may traverse down to any file by a couple of mouse clicks.

Why composite pattern?

The Composite Design Pattern is useful when individual objects as well as a group of those kinds of objects are treated uniformly.

Hmm.., bookish definition. Let's think of a scenario where we want to draw a few shapes in the same canvas. And we will draw all the components in the same way (by calling a respective function). We will try to implement it with a small working example. Have a look at the following code:

  1. using System;  
  2. using System.Collections;  
  3. using System.Globalization;  
  4. using System.Data.SqlClient;  
  5. using System.Data;  
  6. namespace Test1  
  7. {  
  8.     interface IDraw  
  9.     {  
  10.         void Draw();  
  11.     }  
  12.     class Circle : IDraw  
  13.     {  
  14.         public void Draw()  
  15.         {  
  16.             Console.WriteLine("I am Circl");  
  17.         }  
  18.     }  
  19.     class Square: IDraw  
  20.     {  
  21.         public void Draw()  
  22.         {  
  23.             Console.WriteLine("I am Square");  
  24.         }  
  25.     }  
  26.     class Oval : IDraw  
  27.     {  
  28.         public void Draw()  
  29.         {  
  30.             Console.WriteLine("I am Oval");  
  31.         }  
  32.     }  
  33.     class Program  
  34.     {  
  35.         static void Main(string[] args)  
  36.         {  
  37.             ArrayList objList = new ArrayList();  
  38.             IDraw objcircl = new Circle();  
  39.             IDraw objSquare = new Square();  
  40.             IDraw objOval = new Oval();  
  41.             objList.Add(objcircl);  
  42.             objList.Add(objSquare);  
  43.             objList.Add(objOval);  
  44.             foreach (IDraw obj in objList)  
  45.             {  
  46.                 obj.Draw();  
  47.             }  
  48.             Console.ReadLine();  
  49.         }  
  50.     }  

Here, we have created a draw interface and three classes are deriving from them. Now, try to match this class hierarchy with the basic structure of the Composite Design Pattern. Here the IDraw interface is the root node and since three classes are derived from it (here implemented) and all of them are child nodes.

Each and every child class contains the same function definition and that's why we are able to call the Draw() function from each class within the for loop.

Here is sample output of this example:

Composite1.jpg

In the next example we will implement one organization designation scenario in the Composite Design Pattern. We will assume that it is a small organization where employees are categories only in three levels.

CEO
Head Manager
Area Manager


Now, in this example we have implemented the following tree structure.
Composite2.jpg

Since this is the tree structure we can reach any leaf node from any non-leaf node. For example if we start from the root (CEO) node then by traversing the HM (Head Manager) nodes we can easily reach an Area Manager node.

We will consider each node as a class in a sample example. Each class will also contain a common function called Designation(). In the following example we will start from a leaf node and will reach to the root node. Have a look at the following implementation.

  1. using System;  
  2. using System.Collections;  
  3. using System.Globalization;  
  4. using System.Data.SqlClient;  
  5. using System.Data;  
  6. using System.Collections.Generic;  
  7. namespace Test1  
  8. {  
  9.     interface IEmployee  
  10.     {  
  11.         void Designation();  
  12.     }  
  13.     class CEO :IEmployee  
  14.     {  
  15.         public virtual void Designation()  
  16.         {  
  17.             Console.WriteLine("I am sourav.CEO of Company");  
  18.         }  
  19.     }  
  20.     class HeadManager_1:CEO,IEmployee  
  21.     {  
  22.         public override void Designation()  
  23.         {  
  24.             Console.WriteLine("I am Rick. My Boss is sourav");  
  25.         }  
  26.     }  
  27.     class HeadManager_2 : CEO,IEmployee  
  28.     {  
  29.         public override void Designation()  
  30.         {  
  31.             Console.WriteLine("I am Martin. My Boss is sourav");  
  32.         }  
  33.     }  
  34.     class AreaManager:HeadManager_1,IEmployee  
  35.     {  
  36.         public new void Designation()  
  37.         {  
  38.             Console.WriteLine("I am Mack. My Boss is Rick");  
  39.         }  
  40.     }  
  41.     class Program  
  42.     {  
  43.         static void Main(string[] args)  
  44.         {  
  45.             IEmployee AreaManager = new AreaManager();  
  46.             IEmployee Hm_1 = new HeadManager_1();  
  47.             IEmployee CEO = new CEO();  
  48.             List<IEmployee> objEmployee = new List<IEmployee>();  
  49.             objEmployee.Add(AreaManager);  
  50.             objEmployee.Add(Hm_1);  
  51.             objEmployee.Add(CEO);  
  52.             foreach (IEmployee O in objEmployee)  
  53.             {  
  54.                 O.Designation();  
  55.             }  
  56.             Console.ReadLine();  
  57.         }  
  58.     }  

Here is a sample example.

Composite3.jpg

Conclusion

In this article we have seen how to implement a Composite Design Pattern in C#. Hope you have enjoyed it.