Composite design pattern for beginners

Marcio Junior
4 min readApr 4, 2022
Photo by Ihya’ Hakim Hamizul on Unsplash

Introduction

Today we will talk about the Composite design pattern. The intent of this pattern is to compose groups of objects, which in turn can be grouped to form a larger structure. Keep reading to understand why and how this pattern allows us to treat these objects uniformly.

Tree

The Composite pattern uses a tree to represent groups of objects, also know as a hierarchy. Tree is a data structure that has a root and a set of sub-trees connected to each other:

Notice we have a darker node representing the root, and a single node at the right. But in the left side, there is another node that could be considered root too, since it has another two nodes connected to him. This last part works like a mini tree. The Composite design uses this hierarchical structure to represent objects.

Programming to an interface

As presented in the Design Patterns book, the example of a drawing software is a good way to understand this pattern. Imagine you are designing a software that has to draw lines, rectangles, texts, etc. And like other drawing softwares, you may want to change the color or apply some effect on an object, or a group of them. In other words, you want to treat objects and groups uniformly.

To treat objects in the same way, they should have the same set of methods like Draw and SetColor for example. Don’t worry about the implementation of methods here. Just design an interface that can attend the requests (you may want to know the benefits of doing this on this article).

The image above shows two classes, Line and Picture, and both implements the interface IGraphic. The Line is just a single object and Picture represents a group of objects that can be lines, rectangles, etc. Now doesn’t matter which type it is, they will attend the same requests.

Composite structure

As said before, the Composite design pattern uses a tree structure to represent objects. The following diagram shows a typical composite object structure:

The root node is a Picture object and has two children. The left child is another Picture which serves as root for another two objects. The remaining objects are simple nodes. As a Picture represents a group of objects, it should provide a way to store the child objects. So let’s include the method to insert these children on the IGraphic interface:

And implement this in the Picture class:

class Picture : IGraphic
{
List<IGraphic> graphicList = new List<IGraphic>();
public void Add(IGraphic graphic) => graphicList.Add(graphic);
}

Other classes also will be forced to implement Add method, however this operation doesn’t make sense for single node objects. This issue is discussed in the Design Patterns book and involves a trade-off between safety and transparency. Maybe it will cost safety when clients try to do meaningless things like Add from Line object, but it gives transparency because you can treat all components uniformly.

Having addressed that, lets talk about the Draw method or any other operation that can be safety executed by objects. For example, calling Draw on Line objects will draw a line on the screen. But calling Draw on a composite object, will call Draw on its children:

public void Draw()
{
foreach (var graphic in graphicList)
{
graphic.Draw();
}
}

This way we can access the root node children, which in turn can be composed by other children an so on. This is called recursive programming, when a function makes calls to itself — a subject for another article.

Conclusion

In this article I covered some topics on the Composite design pattern like trees, interfaces, compositions and recursion. I hope you enjoyed and check out my GitHub repository to see the complete example. Feel free to comment and get in touch in case of doubts.

--

--