I am going over my design patterns, and one pattern I have yet to seriously use in my coding is the Decorator Pattern.
I understand the pattern, but what I would love to know are some good concrete examples of times in the real world that the decorator pattern is the best/optimal/elegant solution. Specific situations where the need for the decorator pattern is really handy.
Thanks.
The decorator is simple yet extremely powerful. It is key in achieving separation of concerns and is an essential tool for the Open Closed Principle. Take a common example of placing an order for a product:
Main implementation:
AmazonAffiliateOrderGateway
Possible decorators could be:
IncrementPerformanceCounterOrderGateway
QueueOrderForLaterOnTimeoutOrderGateway
EmailOnExceptionOrderGateway
InterceptTestOrderAndLogOrderGateway
Take a look here for a more detailed example.
Decorator pattern is used by C# language itself. It is used to to decorate the Stream I/O class of C#. The decorated versions are BufferedStream, FileStrem, MemoryStrem, NetworkStream and CryptoStream classed.
These subclasses inherit from the Stream class and also contain an instance of the Stream class.
Read more here
Decorator pattern dynamically changes the functionality of an object at run-time without impacting the existing functionality of the objects.
Key use cases:
Drawbacks:
A real world example: Compute the price of beverage, which may contain multiple flavours.
output:
This example computes cost of beverage in Vending Machine after adding many flavours to the beverage.
In above example:
Cost of Tea = 10, Lemon = 3 and Sugar = 5. If you make Sugar + Lemon + Tea, it costs 18.
Cost of Coffee =15, Lemon = 3 and Sugar = 5. If you make Sugar + Lemon + Coffee, it costs 23
By using same Decorator for both beverages ( Tea and Coffee ), the number of sub-classes have been reduced. In absence of Decorator pattern, you should have different sub classes for different combinations.
The combinations will be like this:
etc.
By using same Decorator for both beverages, the number of sub-classes have been reduced. It's possible due to composition rather than inheritance concept used in this pattern.
Related SE question:
Decorator Pattern for IO
Useful links:
design-patterns-decorator by dzone
decorator by sourcemaking
oodesign article
The decorator pattern is used a lot with streams: you can wrap a stream with a stream to get added functionality. I've seen this with the .Net framework - as far as I know this occurs elsewhere. My favourite is using GZipStream around a FileStream, for added compression.
I've recently used the decorator pattern in a web service which uses the following CommandProcessor interface:
Basically, the CommandProcessor receives a Request and creates the proper Command, executes the Command and creates the appropriate Response, and sends the Response. When I wanted to add timing and log it, I created a TimerDecorator that used an existing CommandProcessor as its component. The TimerDecorator implements CommandProcessor interface, but just adds timing and then calls its target, which is the real CommandProcessor. Something like this:
So the real CommandProcessor is wrapped inside TimerDecorator, and I can treat TimerDecorator just like the target CommandProcessor, but now timing logic has been added.