Design Pattern: Decorator Pattern
The Decorator Pattern is another pattern where an object, in this case the decorator, stands in for another object. The Decorator actually wraps itself around the other object and adds functionality to it- hence, “decorating” it.
I think with this pattern working backwards from a complex example better helps to understand it. The example below is from Design Patterns in Ruby and the wiki article on decorators, but I’ve changed a couple names to be even more explicit.
Olsen’s example in “Design Patterns” includes a BasicWriter class that outputs text, and then decorator classes that include LineNumberWriter, TimeStampWriter and CheckSumWriter. All of the decorators inherit their behavior from a WriterDecorator super class, which implements all the methods that SimpleWriter does. The initial super class wraps the original BasicWriter object and implements all of the BasicWriter object’s methods. Here’s an example of that Decorator super class
class WriterDecorator
attr_accessor :basic_writer
def initialize(basic_writer_object)
@basic_writer = basic_writer_object
end
def some_method_in_the_basic_writer_class
@basic_writer.some_method_in_the_basic_writer_class
end
#...all of the other basic_writer methods...
end
So then all of your different decorators inherit from this class so that they can be passed in any BasicWriter object. Then the decorator adds the additional methods it wants to in order to add some functionality to the basic writer.
The kicker is that you can actually wrap decorators in other decorators, hence providing all of the different decorating combinations you need! (Even though I have yet to think of how I’d use this I think it’s pretty cool stuff). Here is Olsen’s example of chained decorators:
writer = CheckSumWriter.new(TimeStampWriter.new(LineNumberWriter.new(BasicWriter.new('your_document.txt'))))
So now we have a Basic Writer that can number lines, stamp the time and check some sums, and we can chain together any combination of these three to build an object that has just the functionality we need. Only need to number lines? Just use that decorator. Want to number lines and stamp the time? Only use those two.
Here’s a version of the UML diagram that appears in “Design Patterns”, the wiki and the original Gang of Four book. It shows how a Decorator inherits from the super class, all of the classes implement the same method, and the decorator adds a method. The one part of of the diagram I don’t get is how it shows the ConcreteComponent (in the example above, our BasicWriter) inheriting from that super class. I don’t think in this case the “open” arrow means inheritance, so that’s another question I’ll ask in the office tomorrow.