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

We will see with an example.

Requirement

Build a smart city with smart block features.

We will define 3 players.

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.

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.