DEV Community

Cover image for Composite Design Pattern
Nicolas
Nicolas

Posted on • Edited on

Composite Design Pattern

Let's talk about the composite pattern, we use this pattern in situation where we want to create a hierarchy of items. This pattern helps us create components that can be grouped or ungrouped to any depth without limitations a good example is a file manager were you can create folders to group files and subfolders.

In this article we are going to look at creating File manager , we won't be using an actual application but I will keep it
as simple as possible by using POCO objects on a console application.

In this session I will be using C# but this can be applied with most languages.

Let's get Started

  1. Creating your solution

Assuming you have .NET SDKs installed on your machine.
Create a new console application witht the following command

dotnet new console -n CompositePattern -o CompositePatterns/src/

  1. Open your project with Visual Studio Code

Before we continue we should understand few concepts like Programming to an interfaces - Coding to interfaces or design by contract is a technique by which developers can expose certain methods of an object to other objects in the system.

In this Pattern we create an interface that will form a contract of all the required features of a groupable component,we than move on to create a leaf class that is just a blueprint class of a component that implements our contract, finally we create a class that represents a group component that is going to be used to group other components ,this group component also has to implement the contract ,this will allow us to groups in groups.

Here is a UML of what a composite pattern looks like :
Image description

Creating Our interface

create a new IComponent interface with the following Code :

namespace CompositePattern;
public interface IComponent
{
    string Name { get; set; }
    void Render();
}
Enter fullscreen mode Exit fullscreen mode

Creating our Leaf

Next we create a leaf that implements our interface,that we are going to call a File, your code should look like this code below :

namespace CompositePattern;
public class File : IComponent
{
    public string Name { get; set; }
    public File(string name) => Name = name;
    public void Render() => Console.WriteLine($"{Name} Component Rendered");
}
Enter fullscreen mode Exit fullscreen mode

in this example our component will get its name from the constructor and on the render method it will simply console log the message " Rendered".

Creating the grouping Component

Next we create a component that will be used to group components and render them all together, we will call this component Folder Component, again I am just using simply classes to showcase the concept , Your Code should look like this :

namespace CompositePattern;
public class Folder : IComponent
{
    public string Name { get; set; }
    public List<IComponent> Children { get; set; } = new();

    public Folder(string name) => Name = name;
    public void Add(IComponent component) => Children.Add(component);
    public void Remove(IComponent component) => Children.Remove(component);
    public void Render()
    {
        Console.WriteLine($"{Name} Rendered");
        Children.ForEach(c => c.Render());
    }
} 

Enter fullscreen mode Exit fullscreen mode

In our example our Folder Component implements IComponent ,this will give it the capability to nest groups and files within groups, the Folder also has a few special functions like Add and Remove , this will be used to add more components to the Folder and Remove Components from the Folder,The magic happens on the implementation of the render function, the Folder component iterates over all its children calling the render function of each Component, This is a very powerful technic.

Finally for our Program we are going to create a few files than folders :

using System;
using CompositePattern;

var musicFolder = new Folder("Music Folder");

musicFolder.Add(new File("ghost.mp3"));
musicFolder.Add(new File("doit.mp3"));
musicFolder.Add(new File("smple.mp3"));

var picturesFolder = new Folder("Pictures");
picturesFolder.Add(new File("banner.png"));
picturesFolder.Add(new File("cover.jpg"));

var homeFolder = new Folder("Home Folder");
homeFolder.Add(musicFolder);
homeFolder.Add(picturesFolder);


homeFolder.Render();

Console.ReadLine();

Enter fullscreen mode Exit fullscreen mode

🥳🥳🥳 We just learned how to use the Composite Pattern.

Top comments (0)