8

I understand completely how to implement the Decorator pattern, and I also understand what it's intent is.

The Decorator is used in one of two cases:

As an alternative to subclassing - when there are multiple characteristics that an object can have, one could use inheritance in order to create subclasses for all the possible combinations. For example, three characteristics A, B and C will results in lots of classes: A, B, C, ABC, AB, AC, BC. This results in a 'class explosion'. With Decorator, one would have three decorators A, B and C, and a class D to 'decorate' - and that's it.

As a way to expand an object's functionality during runtime - we can decide which decorators to 'wrap' an object with during runtime, thus 'customizing' an object dynamically.

This was just to show that I do understand what Decorator is (I also totally understand how it's implemented). Now my question:

I'm familiar with theoretical examples of when and how to use Decorator. And as you can see I know what is it's intent. But I'm still not sure when to actually use this in practice, in an actual application. Telling me "it's used as an alternative to subclassing", or "it's used to dynamically add functionality to an object" won't be helpful since I'm familiar with it's intent.

Also telling me "think of a UI window for example. It can have a border, or not, and can be resizable, or not" isn't helpful, I'm already familiar with these theoretical examples.

So what I'm asking for is a concrete real world example of Decorator, in a practical, real-world scenario, with a brief explanation of the benefits of using a Decorator pattern there over other techniques.


Just to clarify, I'm not looking for a list of applications where Decorator was utilized. I'm looking for an example of where and how Decorator was used in a design, why it was a good design choice and the concrete problem that it solved. When I'll see concrete problem solved with Decorator hopefully I'll understand it better.

13
  • 7
    You may be "familiar" with the Java IO library, but it remains the best example of Decorator that I've seen. I recommend sitting down with the source code of InputStream, Reader, and InputStreamReader and thinking how you might implement the latter without using the Decorator pattern.
    – kdgregory
    Commented May 16, 2014 at 17:39
  • 2
    This sounds like a question requesting a list of things, unfortunately with a list no answer is better than another, they're all just lists of options. As such the resulting content is not really helpful to people in the future because they can't know which answer has more relevant information. Voting to close, sorry. Also your question doesn't make sense, you claim to know when to use a decorate but ask when you should use a decorator. Either you know when people should use them or you don't; which is it? Commented May 16, 2014 at 17:44
  • 2
    Please don't ask for lists of things. That's why your question has three close votes and three downvotes on it. Example(s) (plural) is a list. Commented May 16, 2014 at 18:12
  • 3
    FWIW, Decorator is not all that remarkable. Decorator is a special case of Composition. You wrap a class in another class to change its behavior, or to add some new behavior. You use it when Inheritance is unavailable to you. That's all it is. Commented May 16, 2014 at 18:33
  • 2
    The problem the decorator solves is - an alternative to subclassing. That's it. It doesn't directly solve real world, "concrete" problems. It's like asking for a real world problem solved by addition. Or by polymorphism. The best you will get is when some random application happened to use it. An anecdote about how "addition was vital in my nuclear launch software" won't really tell you much about addition or its purpose. You keep rejecting examples of composition that are as valid as anything you will get.
    – psr
    Commented May 16, 2014 at 18:50

1 Answer 1

9

This was essentially answered by kdgregory in a comment on the question, but ...

A stream is something that can benefit from multiple attributes being added to it, independent of one another. I want a big dump of application data in a stream. Great. I also want it encrypted. Oh, in this case I also want it zipped. From this particular client, I want to change the style of line breaks they use as well.

This is an example of the alternative to subclassing your question mentions. Rather than having LineBreakFixingEncryptingZippingStream (which won't be able to inherit all 3 behaviors and so would lead to code duplication if you already have a LineBreakFixingStream, an EncryptingStream, and a ZippingStream), you can use composition of classes that share a stream interface.

So, LineBreakFixingStream decorates BoringStream, and is implemented by reading from BoringStream and forwarding the reads on to the caller of LineBreakFixingStream, except it changes the line breaks. Then EncryptingStream, which can decorate any stream, can decorate an instance of LineBreakFixingStream that, in this case, is decorating BoringStream. Then ZippingStream can decorate that EncryptingStream. Any combination of your stream classes can be put together pretty easily, even at run time if that is needed (though it isn't in my example - but you can imagine a scenario where clients call an API to put them together as one possible real world scenario that would use run time composition).

Though this is still a little abstract about the purpose, it is a real world scenario. I've composed streams before in real applications. Zipping and encrypting come up frequently, and doing a bit of custom formatting of a client data stream is common as well.

1
  • I'll look into the source of these classes to get a better understanding. Thanks
    – Aviv Cohn
    Commented May 16, 2014 at 18:51

Not the answer you're looking for? Browse other questions tagged or ask your own question.