Back to: Design Patterns in C# With Real-Time Examples
Composite Design Pattern Real-Time Example using C#
In this article, I am going to discuss Composite Design Pattern Real-Time Examples using C#. Please read our previous article where we discussed the basic concepts of Composite Design Patterns in C#. The Composite Design Pattern belongs to Structural Design Pattern Category and hence deals with Object Composition.
What is Composite Design Pattern?
The Composite Design Pattern composes the objects in the form of a tree structure to represent the Part-Whole Hierarchy. That means we access the operations of an individual object as well as we can access the operations on a composite object in the same manner.
Real-Time Example to Understand Composite Design Pattern:
Now, we need to create an application to show the Employee details along with the Salary details. We need to make the application show flexible so that we can get the salary of a particular employee, we can get all the employee’s details, and the total salary of a particular department of an organization. We also need to get all the employees and their total salary of the company. But the important thing is, we need to access the employee salary in a similar manner. That means we will create one method and we will call that method from the Individual objects as well as from the composite complex object.
Let us first see the pictorial representation of the Employee hierarchy in the company. For a better understanding, please have a look at the following diagram which shows the Company, Department, and Employees department-wise.
Whatever you see in the above diagram, everything is an object. So, here, Company, ITDepartment, HRDepartment, Pranaya, Rohit, Anurag, Priyanka, and Sambit, all are objects. A Composite Object is an object which contains other objects. The object which does not contain any other objects is simply treated as a Leaf Object. So, in our example, Company, ITDepartment, and HRDepartmentare Composite Objects or Composite Components while Pranaya, Rohit, Anurag, Priyanka, and Sambit are the Leaf Objects.
What is Our Requirement?
Our Requirement is to get the employee’s name and salary. We need to design the application in such a way that we should be able to access the employee name and salary of any particular employee like Pranaya, Rohit, Anurag, etc, i.e. accessing the leaf object. We also need to allow the client to get the employee’s name and salaries in any particular department. For example, if the client wants to know the employees and their salaries working IT Department, then our application should display those employees and their salaries who are working in the IT Department along with the total salary of the IT Department. The same is the case for HR Department.
Similarly, If the client wants to know the name and salaries of all employees working in the company, then the application should able to display all the employee’s name and their salaries along with the total salary.
That means we need to define one method, let us say GetSalary and the client should be able to call this method on individual leaf objects as well as should be able to call this method on composite objects in the same manner. And. this is possible by using Composite Design Pattern. Let us proceed and implement this Real-Time Example using Composite Design Pattern in C#.
Step1: Creating Component Interface or Abstract Class
Create a class file with the name Component.cs and then copy and paste the following code into it. The following Component abstract class declares the common operations for both Leaf and Composite objects. In our example, we need to show the employee’s name and salary as well as we need to return the employee’s salary. So, here you can see, we have declared one method called GetSalary which is going to be implemented by both Leaf and Composite components. The following example code is self-explained, so please go through the comment lines for a better understanding.
namespace CompositeDesignPatternExample { // The Base Component Abstract class declares the common operations for both Leaf and Composite objects. public abstract class Component { //This Property is used to store the Component Name public string Name { get; } //Initializing the Name Property using Class Parameterized Constructor public Component(string name) { this.Name = name; } //The following GetSalary method is going to be overridden in both Leaf and Composite classes public abstract int GetSalary(); } }
Step2: Creating Leaf Component
The Leaf component represents the actual objects i.e. the actual employee which has a name and salary. A leaf component cannot have any children. So, create a class file with the name Leaf.cs and then copy and paste the following code into it. The following name class implements the Component abstract class and provides implementations for the GetSalary method. As part of this class, we are creating one property i.e. Salary to return the salary of the employee. As part of the GetSalary method, first, we are displaying the Name and Salary of the Employee and then we are returning the Salary of the Employee. We are initializing the Name and Salary Properties using the class constructor. The following example code is self-explained, so please go through the comment lines for a better understanding.
using System; namespace CompositeDesignPatternExample { // This is going to be our Leaf class that represents the actual end objects. // A leaf Component can not have any children components. // The Leaf object is the Object which does the actual work public class Leaf : Component { //The following Property is going to hold the salary of the Employee public int Salary { get; } //While creating the Leaf Object, //we need to pass the Name and the Salary of the Employee //The Employee Name we need to pass to the Base class constructor //Initializing the Salary Property using the Constructor public Leaf(string Name, int Salary) : base(Name) { this.Salary = Salary; } //We need to override the following GetSalary method to provide the actual implementation public override int GetSalary() { //We are Printing the Name and Salary of the Employee and then returning the Salary Console.WriteLine($"\t Name: {Name} and Salary: {Salary}"); return Salary; } } }
Step3: Creating Composite Object
The Composite class represents the composite components i.e. the component that has children. The Composite objects delegate the actual work to their children and then combine the result. So, create a class file with the name Composite.cs and then copy and paste the following code into it. As this class is going to be our composite class, so we are creating a variable i.e. ChildComponents to hold its child components. Again, we are initializing the component name property using the class constructor. Using the AddComponent() method we are adding child components inside the ChildComponents variable. Again, using the RemoveComponent() method, we are removing the child component from the ChildComponents variable.
This class also implements the Component abstract class and overrides the GetSalary method. As part of the GetSalary() method, we are returning the sum of the salary of all children components which is inside this composite, and to do this, we are internally calling the GetSalary method on the child component object. The following example code is self-explained, so please go through the comment lines for a better understanding.
using System.Collections.Generic; using System.Linq; namespace CompositeDesignPatternExample { // This is going to be a class that represents the Composite Component. // A Composite Object is an Object which has Child Component. // The Children Component Can be a Leaf Object or Can be another Composite Object // The Composite object delegate the actual work to their children and then combines the result. public class Composite : Component { //The Following ChildComponents variable is going to hold all the child components of a composite object private List<Component> ChildComponents = new List<Component>(); //The Constructor takes the Composite Component name as the input parameter //and passed that parameter value to the base class constructor public Composite(string name) : base(name) { } //The following Method is used to add Child Components inside the Composite Component public void AddComponent(Component NewComponent) { this.ChildComponents.Add(NewComponent); } //The following Method is used to Remove Child Components from the Composite Component public void RemoveComponent(Component RemoveComponent) { this.ChildComponents.Remove(RemoveComponent); } //Override the Component class GetSalary Method public override int GetSalary() { //int TotalSalary = 0; //foreach (var component in ChildComponents) //{ // var salary = component.GetSalary(); // TotalSalary += salary; //} //return TotalSalary; // Summarizing the Salary of all children return this.ChildComponents.Sum(x => x.GetSalary()); } } }
Step4: Client Code
The client code works with all of the components (Both Leaf and Composite) via the base abstract class Component i.e. the class that implements the component abstract class. In our example, both Leaf and Composite classes implement the Component abstract class. The Main method of the Program class is going to be the client. So, please modify the Main method of the Program class as shown below. Here, we are creating the tree structure and then show the respective component details by calling the GetSalary method. Here, you can see, we are creating leaf objects, we are creating composite objects, and then calling the GetSalary method on both Leaf objects as well as Composite objects. The following example code is self-explained, so please go through the comment lines for a better understanding.
using System; namespace CompositeDesignPatternExample { public class Program { static void Main(string[] args) { // The client code works with all of the components (Both Leaf and Composite) via the base interface i.e. Component. // Component means the class that implements the Component abstract class // In our example Leaf and Composite classes implement the Component abstract class //Creating Leaf Objects or you can say child objects Component Pranaya = new Leaf("Pranaya", 22000); Component Rohit = new Leaf("Rohit", 33000); Component Anurag = new Leaf("Anurag", 42000); Component Priyanka = new Leaf("Priyanka", 52000); Component Sambit = new Leaf("Sambit", 28000); //Creating Composite Objects Composite ITDepartment = new Composite("ITDepartment"); Composite HRDepartment = new Composite("HRDepartment"); Composite Company = new Composite("Company"); //Creating Tree Structure i.e. Adding Child Components inside the Composite Component //Adding Pranaya, Rohit, and Anurag to ITDepartment Composite Object ITDepartment.AddComponent(Pranaya); ITDepartment.AddComponent(Rohit); ITDepartment.AddComponent(Anurag); //Adding Priyanka and Sambit in HRDepartment Composite Object HRDepartment.AddComponent(Priyanka); HRDepartment.AddComponent(Sambit); //Adding ITDepartment and HRDepartment inside Company Composite Object Company.AddComponent(ITDepartment); Company.AddComponent(HRDepartment); Console.WriteLine("All Employees of the Company"); //To Display the Price of the Computer i.e. it will display the Price of all components Console.WriteLine($"Total Salary of the Company: {Company.GetSalary()}"); //To display Salaries and Employees of the IT Department Console.WriteLine("\nIT Department Employees"); Console.WriteLine($"Total Salary of IT Department: {ITDepartment.GetSalary()}"); //To display Salaries and Employees of the HR Department Console.WriteLine("\nHR Department Employees"); Console.WriteLine($"Total Salary of HR Department: {HRDepartment.GetSalary()}"); //To display Salaries and Employees of HR Department Console.WriteLine("\nSalary of Employee Pranaya:"); Pranaya.GetSalary(); Console.WriteLine($"\nSalary of Employee Anurag: "); Anurag.GetSalary(); Console.Read(); } } }
Output:
UML or Class Diagram of Composite Design Pattern:
Please have a look at the following image to understand the Class Diagram or UML Diagram of the Composite Design Pattern and understand the different components involved in the Composite Design Pattern.
There are four participants involved in the Composite Design Pattern. They are as follows:
- Component: This is going to be an abstract class or interface containing the members that will be implemented by both Leaf and Composite objects.
- Leaf: This is going to be a class that represents the Leaf Object. A leaf object cannot have any children. This class should implement the Component abstract class.
- Composite: This going to be a class that defines the behavior of the Composite Components. A Composite Object means a component that has children. This class should also implement the Component abstract class.
- Client: In our example, the Main method of the Program class is going to be the client. The Client Code will work with all of the components (Both Leaf and Composite) via the base abstract class i.e. Component.
In the next article, I am going to discuss the Flyweight Design Pattern in C# with Examples. Here, in this article, I try to explain Composite Design Pattern Real-Time Example. I hope, now you enjoy this Composite Design Pattern Real-Time Example article.
About the Author: Pranaya Rout
Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.
please explain examle with Unity game devlopment uses