Design Patterns #3: Decorator

Design pattern number 3 – decorator. The decorator allows to dynamically modify behaviour of an object, and by ‘modify’ I not necessarily mean to swap completely.
The idea behind decorator pattern is that you take an object and wrap it with another object. Calling the outer object (decorator) will in turn call the inner object (component) and before returning any value will do its part with the value.

The example given in the book is a coffee shop where base coffee can be decorated with multiple toppings such as cream, sugar etc. And all those addition will make their own impact on price and name. The important is that the base product (component) and the decorator implements the same interface, the difference is that the decorator has a reference to the component.

And while the decorator itself can be a component it also can be decorated. And so on, and so on… Let’s take a look at the exemplary diagram: the decorator implements the component’s interface and has a reference to a component (we can say in short: the decorator has a component and is a component).

CODE EXAMPLE
Let’s now move on to the code example. My example will be similar to one presented in the book – orders that can be decorated with discounts, extra costs etc. So let’s start with abstractions.

Abstractions
Our IOrder interface will have its name and cost. Decorator interface will extend IOrder with property of IOrder type with public getter only.

Implementations
Concrete classes will be very simple. Order class will have two automatic properties (with private setters) and a constructor that sets those properties.

Things get a bit more complicated with the decorators. Here I will describe only one example but in the source code linked at the bottom of the page you will find two more (however they are very similar). The most important difference (as indicated already twice in this post ;)) is that the decorator has a reference to IOrder object. It will be set int he constructor. As this decorator’s purpose is to apply discount  to the order we will need another property for that (of type int and it will also be set in the constructor). Now the essence of the pattern. As the decorator itself is of type IOrder we need to implement Cost and Name properties. These properties will call counterparting properties in referenced IOrder object, get their values and modify them appropriately. In this case the cost will be reduced by discount value and the name will be equipped with a suffix informing about the discount. We can build as many decorators as we please, and use them as many as we please.

Usage
To test our orders and their decorators we’re gonna instantiate a pack of orders, decorate them and decorate again. They all will be stored in a list and then we will iterate through the list and print to screen their names and cost.

All works perfectly:

That’s it for today. Next week it will be time for factories. So I hope we see again!

Source code: download txt file