Composite Design Pattern in C#

Composite Design Pattern in C# with Examples

In this article, I am going to discuss the Composite Design Pattern in C# with some examples. Please read our previous article where we discussed the Bridge Design Pattern in C# with examples. The Composite Design Pattern falls under the category of Structural Design Pattern. As part of this article, we are going to discuss the following pointers.

  1. What is the Composite Design Pattern?
  2. When do we need to use the Composite Design pattern?
  3. Understanding the Composite Design Pattern
  4. Implementing the Composite Design Pattern in C#
What is the Composite Design Pattern?

As per the Gang of Four definitions, the Composite Design Pattern states that “Compose objects into tree structures to represent part-whole hierarchies. Composite let clients treat individual objects and compositions of objects uniformly”. 

In simple words, we can say that the composite pattern composes the objects in terms of a tree structure to represent part as well as a whole hierarchy. The composite design pattern is used when we need to treat a group of objects in a similar way as a single object. If this is not clear at the moment, then don’t worry we will try to understand this with an example.

Understanding the Composite Design Pattern:

The term composite means a thing made of several parts or elements. Let us understand the composite design pattern with one real-time example. Here we want to assemble a computer. As we know a computer is made of several parts or elements integrated together as shown in the below image.

Understanding the Composite Design Pattern in C#

As shown in the above image, everything is an object. So, here, Computer, Cabinet, Peripherals, Hard Disk, Mother Board, Mouse, Keyboard, CPU, RAM, etc. all are objects.

A composite object is an object which contains other objects. The point that you need to remember is a composite component may also contain other composite objects. The object which does not contain any other objects is simply treated as a leaf object.

So, in our example, the Computer, Cabinet, Peripherals, Mother Boards are composite objects while Hard Disk, CPU, RAM, Mouse and Keyboard are the leaf object which is shown in the below diagram.

Composite Design Pattern in C#

All the above objects are the same type i.e. Electronics type. For example, if we talk about a computer it is an electronic device. If we talk about the motherboard, it is an electronic device and similarly, if we talk about Mouse, it is also an electronic device. That means they follow the same structure and feature. For example, all the above objects having a price. So, you may ask the price for a Keyboard or Mouse or Motherboard of even though the price of a computer.

When you are asking the price for Keyboard it should show you the price of Keyboard. But when you are asking the Price for the motherboard, then it needs to display the Price of RAM and CPU. Similarly, when you are asking the price of the computer, then it needs to display all the prices.

The composite design pattern will be having a tree structure having composite objects and leaf objects. The fundamental idea is if you perform some operation on the leaf object then the same operation should be performed on the composite objects. For example, if I am able to get the price of a Mouse, then I should be able to get the Price of Peripherals and even I should be able to get the Price of the Computer object. If you want to implement something like this, then you need to use the Composite Design Pattern.

Let us implement the Composite Design Pattern in C#.

Step1: Create an interface

Create an interface with the name IComponent and then copy and paste the following code. The common functionalities are going to be defined here. For our example, it is going to be showing the price of a component.

namespace CompositeDesignPattern
{
    public interface IComponent
    {
        void DisplayPrice();
    }
}
Step2: Creating Leaf class

Create a class file with the name Leaf.cs and then copy and paste the following code in it. This class implements the IComponent interface and hence we are providing the implementation for the DisplayPrice method. As part of this class, we are creating two properties to display the component name and price and we are initializing these two properties using the parameterized constructor. And finally, we are displaying these two values in the DisplayPrice method.

using System;
namespace CompositeDesignPattern
{
    public class Leaf : IComponent
    {
        public int Price { get; set; }
        public string Name { get; set; }

        public Leaf(string name, int price)
        {
            this.Price = price;
            this.Name = name;
        }
        
        public void DisplayPrice()
        {
            Console.WriteLine(Name +" : "+ Price);
        }
    }
}
Step3: Creating Composite class

Create a class file with the name Composite.cs and then copy and paste the following code in it. As this class is going to be our composite class, so we are creating a variable to hole the component name and another variable to hold its child components. Again we are initializing the name property using the class constructor. Using the AddComponent method we are adding the child components. This class also implements the IComponent interface and as part of the DisplayPrice() method, first, we print the component name and then show the price of all the leaf nodes using a loop.

namespace CompositeDesignPattern
{
    public class Composite : IComponent
    {
        public string Name { get; set; }
        List<IComponent> components = new List<IComponent>();

        public Composite(string name)
        {
            this.Name = name;
        }

        public void AddComponent(IComponent component)
        {
            components.Add(component);
        }
        
        public void DisplayPrice()
        {
            Console.WriteLine(Name);
            foreach (var item in components)
            {
                item.DisplayPrice();
            }
        }
    }
}
Step4: Client Program

Please modify the Main method of the Program class as shown below. Here, we are creating the tree structure and then showing the respective component price by calling the DisplayPrice method.

using System;
namespace CompositeDesignPattern
{
    public class Program
    {
        static void Main(string[] args)
        {
            //Creating Leaf Objects
            IComponent hardDisk = new Leaf("Hard Disk", 2000);
            IComponent ram = new Leaf("RAM", 3000);
            IComponent cpu = new Leaf("CPU", 2000);
            IComponent mouse = new Leaf("Mouse", 2000);
            IComponent keyboard = new Leaf("Keyboard", 2000);

            //Creating composite objects
            Composite motherBoard = new Composite("Peripherals");
            Composite cabinet = new Composite("Cabinet");
            Composite peripherals = new Composite("Peripherals");
            Composite computer = new Composite("Computer");

            //Creating tree structure
            //Ading CPU and RAM in Mother board
            motherBoard.AddComponent(cpu);
            motherBoard.AddComponent(ram);

            //Ading mother board and hard disk in Cabinet
            cabinet.AddComponent(motherBoard);
            cabinet.AddComponent(hardDisk);

            //Ading mouse and keyborad in peripherals
            peripherals.AddComponent(mouse);
            peripherals.AddComponent(keyboard);

            //Ading cabinet and peripherals in computer
            computer.AddComponent(cabinet);
            computer.AddComponent(peripherals);

            //To display the Price of Computer
            computer.DisplayPrice();
            Console.WriteLine();

            //To display the Price of Keyboard
            keyboard.DisplayPrice();
            Console.WriteLine();

            //To display the Price of Cabinet
            cabinet.DisplayPrice();

            Console.Read();
        }
    }
}
When do we need to use the Composite Design pattern?

We need to use the Composite Design Pattern when

  1. We want to represent part-whole hierarchies of objects.
  2. We want the clients to ignore the difference between compositions of objects and individual objects.

In the next article, I am going to discuss the Proxy Design Pattern in C# with some examples. Here, in this article, I try to explain the Composite Design Pattern in C# step by step with some simple examples. I hope you understood the need and use of the Composite Design Pattern in C#.

Leave a Reply

Your email address will not be published. Required fields are marked *