Continuing with my post with design patterns today I am going to talk about another useful design pattern called thedecorator pattern. This pattern like the Adapter pattern is very simple and quite useful. Lets see the definition of decorator pattern in wikipedia.
That’s pretty good as we are always trying to build software which are loosely coupled, highly extensible and flexible and this pattern will help us a lot in achieving our goals.
As usual we will start with a UML class diagram then we will understand what role each class in the pattern and then start writing some code
And the role of each classes in this pattern are:
- Component: This is the class which defines the interface to which we want to add behavior.
- Concrete Component:: The actual class which implements the interface and has the attribute to which we want to add more behavior/decorators.
- Decorator: The class which acts as glue between the concrete component and the behavior.
- Concrete Decorator: The actual decorator which adds that behavior.
Well you might be wondering what the heck it all means and how I am going to build something which has a decorator pattern in it. Well lets start with a domain problem, lets say you have Product Repository class which brings a list of Products and lets see how it all looks in the class diagram.
No surprises there and lets see the code before we start re factoring and implementing the decorator pattern.
Well looks pretty good and does it jobs we have nice separation of concern (SOC) and good interface dependencies and constructor injection, all in all simple and easy code. But lets say one of the requirements by the business is that the price of the product must apply some discount and also an exchange rate needs to be applied for selling the product on other countries. At this point you might say lets modify the ProductRepository class and add that.But doing this you are violating the Open/Close principle of the SOLID principles and really it is not your repository class responsibility to handle this.
Well then you might say we will change it through a stored procedure to do that and which is not a good idea as we are seeing the trend is moving more towards Domain Driven Development and we don’t want to go backwards.
Lets break down the problem so that we can find a better solution, as we know that Product class has got some attributes and most of them are straight forward and may have one to one representation in terms of the data and how it is persisted,however it’s one attribute which is Price which needs some sort of behaviour or decoration depending on certain conditions.
That’s a good start and in order to add flexibility we convert this into an interface. If you remember some of my design patterns blogs one of the easiest way to club up disparate objects or behaviour is using an interface.
So lets define a simple interface IPrice which encapsulates the Price/Cost attribute of the Product class.
So what we are saying with this interface is that as long as there are classes which implement this interface can act and change (decorate) this property . I know this sounds a bit confusing and time to see some more code to understand the bigger picture. First I will show you how the Product class looks like.
This is the moment where you can see rather than just writing some code we are moving more into engineering a solution. So here in the product class we have created a hook for this interface so that we can latch other classes which have the same interface and it’s these other classes(the decorators) which can change/manipulate the attribute or the behaviour. Lets see how is that achievable in code.
Wow this looks cool as you can see we are getting nice code and good separation of concerns.Of course I have hard corded some of the mathematical calculation for easy illustration and can be easily wrapped with the strategy pattern to apply what kind of calculation(strategy) to apply for which class.
Anyway so far looks good and lets see how we are going to create the decoration code and as most of you have guessed it right it is using the extension method, in fact you can easily say that extension method is .NET’s implementation of decorator pattern from a framework point of view .
As you can see each of these class are well defined and they are following the SOLID principles with use of Single Responsibility Principle and Open/Close Principle.Now lets build the final piece of the puzzle that is the new and improved ProductService class which will still call the same ProductRepository class to get the list of products and then simple decorate it with the two define decorators and will apply the behavior.
Lets write a simple unit test to see how we will call the method in the Product Service class.
I know I am a bit guilty here for not writing a good test, ideally I should assign the base price for all the products as some multiple of 10s and see each of the price being return as some percentage of the value due to the discount and exchange rate but I hope the TDD guys will spare me as it’s more about the decorator pattern.
And now if you look at the final implementation in VS class diagram you will see how close it is to the initial UML diagram in the beginning.
Sideline note:-I have been trying to complete this blog for the last three days and learned my lesson that watching comedy movies and writing blog doesn’t play that well