Composite Design Pattern With C#

Introduction

 
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 composite player, this player will complete the system hierarchy for 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 Abstract block with Add, Remove block features. If we want we can implement Add, Remove features explicitly. In my case I am using List, by default I will be having Add, and Remove features available for adding/removing blocks. 
  1. using System.Collections.Generic;  
  2.   
  3. namespace Composite.Design.Pattern.Demo.Contract  
  4. {  
  5.     public abstract class AbstractBlock  
  6.     {  
  7.         public string Name { getset; }  
  8.         public double Size { getset; }  
  9.         public abstract void BuildBlock();  
  10.         public List<AbstractBlock> SubBlocks { getset;}  
  11.     }  
  12. }  
Now implement Composite object; i.e., Block by implementing/inheriting component i.e. in our code AbstractBlock
  1. using Composite.Design.Pattern.Demo.Contract;  
  2. using System.Collections.Generic;  
  3. using static System.Console;  
  4.   
  5. namespace Composite.Design.Pattern.Demo.Business  
  6. {  
  7.     public class Block : AbstractBlock  
  8.     {  
  9.         public Block()  
  10.         {  
  11.             SubBlocks = new List<AbstractBlock>();  
  12.         }  
  13.         public override void BuildBlock() => WriteLine($"Block built with Name {Name} with size {Size} unit");  
  14.     }  
  15. }  
In the above code we can see that, we provided the implementation for BuildBlock method. Based on our need we can make concrete or non-concreate method as well.
 
Below is the client class code:
  1. using Composite.Design.Pattern.Demo.Contract;  
  2. using static System.Console;  
  3. using Composite.Design.Pattern.Demo.Business;  
  4. using Newtonsoft.Json;  
  5.   
  6. namespace Composite.Design.Pattern.Demo  
  7. {  
  8.     class Client  
  9.     {  
  10.         static void Main(string[] args)  
  11.         {  
  12.             AbstractBlock smartCity = new Block  
  13.             {  
  14.                 Name = "SmartCity",  
  15.                 Size = 100000  
  16.             };  
  17.   
  18.             AbstractBlock smartlayOut = new Block()  
  19.             {  
  20.                 Name = "SmartlayOut",  
  21.                 Size = 10000,  
  22.             };  
  23.             smartCity.SubBlocks.Add(smartlayOut);  
  24.   
  25.             AbstractBlock smartHome = new Block()  
  26.             {  
  27.                 Name = "smartHome",  
  28.                 Size = 1000,  
  29.             };  
  30.             smartlayOut.SubBlocks.Add(smartHome);  
  31.   
  32.             AbstractBlock smartRoom = new Block()  
  33.             {  
  34.                 Name = "smartRoom",  
  35.                 Size = 1000,  
  36.             };  
  37.             smartHome.SubBlocks.Add(smartRoom);  
  38.   
  39.             AbstractBlock smartLocker = new Block()  
  40.             {  
  41.                 Name = "smartLocker",  
  42.                 Size = 20,  
  43.             };  
  44.             smartRoom.SubBlocks.Add(smartLocker);  
  45.   
  46.             AbstractBlock smartFolder = new Block()  
  47.             {  
  48.                 Name = "smartFolder",  
  49.                 Size = 10,  
  50.             };  
  51.             smartRoom.SubBlocks.Add(smartFolder);  
  52.   
  53.             AbstractBlock smartFile = new Block()  
  54.             {  
  55.                 Name = "smartFile",  
  56.                 Size = 5,  
  57.             };  
  58.             smartFolder.SubBlocks.Add(smartFile);  
  59.   
  60.             Build(smartCity);  
  61.             WriteLine();  
  62.             string json = JsonConvert.SerializeObject(smartCity, Formatting.Indented);  
  63.             WriteLine(json);  
  64.   
  65.             ReadLine();  
  66.         }  
  67.   
  68.         private static void Build(AbstractBlock block)  
  69.         {  
  70.             block.BuildBlock();  
  71.             block?.SubBlocks?.ForEach(b => Build(b));  
  72.         }  
  73.     }  
  74. }  
In above code we can see that the client has utilized composite object and built 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 object into Json. Below is the 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 the simple example of using composite design pattern, you can download the uploaded source code and try adding more blocks. I hope it helps.