The Composite design pattern is a structural design pattern that allows us to compose objects into a tree structure and then work with that structure as if it is a single object. That also means using this design pattern makes sense when the part of our app can be represented as a tree.

In this article, we are going to learn how to implement the Composite Design Pattern into our project and what are its benefits.

The source code is available at the Composite Design Pattern – Source Code.

For the main page of this series check out C# Design Patterns.

This article is divided into the following sections:

Composite Design Pattern Structure

The Composite design pattern consists of the following parts:

  • Component
  • Leaf
  • Composite

A component is an interface that describes operations that are common to either simple or complex elements of the tree.

A leaf is a single object, that doesn’t have sub-elements. Our tree structure consists of more leaf objects.

Composite is an object that does have sub-elements (leaves or other composite objects). Interesting thing is that the Composite object isn’t familiar with the concrete classes of its children. It communicates with its children via the Component interface.

Finally, we have a client, which works with all the elements through the Component interface.

But enough of the theory, let’s start with the concrete example.

Composite Design Pattern Implementation

Let’s imagine that we need to calculate the total price of a gift which we are selling in our shop. The gift could be a single element (toy) or it can be a complex gift that consists of a box with two toys and another box with maybe one toy and the box with a single toy inside. As we can see, we have a tree structure representing our complex gift so, implementing the Composite design pattern will be the right solution for us.

So, let’s start with the Component part:

We can see that our component consists of two protected fields and one abstract method. These fields and method are going to be used as an interface between the Leaf and the Composite part of our pattern.

Now, in many examples, we can see additional operations like add and remove inside the abstract class, but we are not going to add them in this class, because our Leaf class doesn’t need them. What we are going to create instead is a new interface – IGiftOperations:

Only our composite object will implement this interface, but the leaf object won’t. This is much better because our leaf object doesn’t need to implement the methods it won’t use.

The Composite Class Implementation

So, let’s continue on with the Composite class:

The class implementation is pretty straightforward. First, we have the GiftBase type list in which we store our Leaf or other Composite objects. We can add or remove those objects from our list by implementing Add and Remove methods from our IGiftOperations interface. Finally, we are calculating the total price of our Gift object with all the sub-gifts inside it.

The Leaf Class Implementation

Let’s continue on with the leaf part:

And that is all we need for the Leaf implementation because it doesn’t have a sub-levels so it doesn’t require to add or remove features at all.

Finally, we can implement our client part:

We can see, that we are creating one gift with just one element inside it and one complex gift with the toys and an additional box with a single toy inside.

So, as soon as we run our app, we are going to get this result:

Composite - result

Excellent. That wraps it up for the Composite design pattern.

Conclusion

Even though this pattern might look a bit complex, it is very beneficial to use it when we have complex tree structures in our code.

Furthermore, by having a single interface that is shared by all the elements in the Composite pattern, the client doesn’t have to worry about the concrete class it works with.

If you have enjoyed reading this article and if you would like to receive the notifications about the freshly published .NET Core content we encourage you to subscribe to our blog.