Composite Design Pattern With C#

Introduction

A composite design pattern is a structural design pattern. It allows developers to create multiple nested objects of the same type to complete one single system hierarchy.

Players in this pattern

  • Component: This player defines base contract with composite class to allow the creation of nested objects.
  • Composite: This the player that will implement the contract defined by the component.
  • Client: With the help of a composite player, this player will complete the system hierarchy for a particular requirement.

We will see with an example.

Requirement

Build a smart city with smart block features.

We will define 3 players.

  • AbstractBlock Component
  • Block Composite
  • Client

We will build an Abstract block with Add and remove block features. If we want we can implement Add and Remove features explicitly. In my case I am using List, by default I will have Add, and Remove features available for adding/removing blocks.

using System.Collections.Generic;

namespace Composite.Design.Pattern.Demo.Contract
{
    public abstract class AbstractBlock
    {
        public string Name { get; set; }
        public double Size { get; set; }
        public abstract void BuildBlock();
        public List<AbstractBlock> SubBlocks { get; set; }
    }
}

Now implement Composite object; i.e., Block by implementing/inheriting component i.e. in our code AbstractBlock.

using Composite.Design.Pattern.Demo.Contract;
using System.Collections.Generic;
using static System.Console;

namespace Composite.Design.Pattern.Demo.Business
{
    public class Block : AbstractBlock
    {
        public Block()
        {
            SubBlocks = new List<AbstractBlock>();
        }
        public override void BuildBlock() => WriteLine($"Block built with Name {Name} with size {Size} unit");
    }
}

In the above code we can see that, we provided the implementation for the BuildBlock method. Based on our needs we can make concrete or non-concreate methods as well.

Below is the client class code.

using Composite.Design.Pattern.Demo.Contract;
using static System.Console;
using Composite.Design.Pattern.Demo.Business;
using Newtonsoft.Json;

namespace Composite.Design.Pattern.Demo
{
    class Client
    {
        static void Main(string[] args)
        {
            AbstractBlock smartCity = new Block
            {
                Name = "SmartCity",
                Size = 100000
            };

            AbstractBlock smartlayOut = new Block()
            {
                Name = "SmartlayOut",
                Size = 10000,
            };
            smartCity.SubBlocks.Add(smartlayOut);

            AbstractBlock smartHome = new Block()
            {
                Name = "smartHome",
                Size = 1000,
            };
            smartlayOut.SubBlocks.Add(smartHome);

            AbstractBlock smartRoom = new Block()
            {
                Name = "smartRoom",
                Size = 1000,
            };
            smartHome.SubBlocks.Add(smartRoom);

            AbstractBlock smartLocker = new Block()
            {
                Name = "smartLocker",
                Size = 20,
            };
            smartRoom.SubBlocks.Add(smartLocker);

            AbstractBlock smartFolder = new Block()
            {
                Name = "smartFolder",
                Size = 10,
            };
            smartRoom.SubBlocks.Add(smartFolder);

            AbstractBlock smartFile = new Block()
            {
                Name = "smartFile",
                Size = 5,
            };
            smartFolder.SubBlocks.Add(smartFile);

            Build(smartCity);
            WriteLine();
            string json = JsonConvert.SerializeObject(smartCity, Formatting.Indented);
            WriteLine(json);

            ReadLine();
        }

        private static void Build(AbstractBlock block)
        {
            block.BuildBlock();
            block?.SubBlocks?.ForEach(b => Build(b));
        }
    }
}

In the above code, we can see that the client has utilized a composite object and built the first Smart City followed by Smart Layout.

  • Smart Layout followed by Smart Home
  • Smart Home followed by Smart Room
  • Smart Room followed by Smart Locker
  • Smart Locker followed by Smart Folder
  • Smart Folder followed by Smart File

After executing this code we can see the same hierarchy in JSON format. For easy understating, I Serialized the object into JSON. Below is the output.

Output

When we have a requirement of implementing some nested objects with the same type then we can go for this design pattern.

We can extend this composite object to any extent with N number of blocks inside blocks.

Summary

Above is a simple example of using a composite design pattern, you can download the uploaded source code and try adding more blocks. I hope it helps.


Similar Articles