In this article, we are going to talk about another structural C# design pattern, the Decorator Design Pattern. We are going to learn, how to implement this pattern in our project and what we can get by doing that.

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

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

This article is divided into the following sections:

About the Decorator Design Pattern

A Decorator is a structural design pattern that allows us to extend the behavior of objects by placing these objects into a special wrapper class. The Decorator design pattern is quite popular in C# due to the fact that it helps us dynamically add behaviors to the wrapped objects.

The structure of this pattern consists of a Component class and a Concrete Component class from one part and a Decorator class and a Concrete Decorator class on the other side. The Concrete Decorator class is going to add additional behavior to our Concrete Component.

So, when do we use this pattern?

Well, we should use this pattern when we have a need to add additional behavior to our objects. Furthermore, we should use it when it is too complicated to use inheritance or when it doesn’t make sense at all (too many inherit layers, urge to modify existing inheritance hierarchy by adding some additional layers, etc.).

We are going to see how all these elements work together inside the Decorator design pattern through the practical example, which is going to make this pattern easier to comprehend.

Decorator Design Pattern Implementation

Let’s imagine that we have a simple application to calculate the total order price in our shop. But also, we have some additional requests. If a buyer orders our products in a preorder period we are going to give a 10 percent discount. So, let’s start first with our Component class:

The Component class contains functionality that will be shared with other Concrete Component classes. Having that in mind, let’s create the Concrete Components:

This code is pretty clean and easy to understand. We just override our abstract method CalculateOrderPrice and calculate the total price. So, right now, we can start using these concrete components:

This works just fine.

But now, we receive an additional request to allow an additional 10 percent discount to our premium users for the preorder. Of course, we could only change the Preorder class with one if statement to check if our user is a premium user, but that would break the Open Closed Principle. So, in order to implement this additional request, we are going to start with a Decorator class which is going to wrap our OrderBase object:

Now, we can implement the PremiumPreorder (Concrete Decorator) class:

In this class, we are calculating the total price of the OrderBase object but also adding the additional discount behavior.

Finally, we can modify the Program.cs class:

As we can see, with the premiumPreorder object we are wrapping the preOrder object to which we add an additional behavior:

Decorator Design Pattern - Result

Now we can clearly see how our Decorator class wraps the preorder object.

Excellent.

Conclusion

In this article, we have learned:

  • What is the Decorator design pattern
  • When should we use it
  • How to implement this pattern in practice

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.