When to Use the Decorator Pattern?
The Decorator
Pattern is used for adding additional functionality to an existing object
(i.e. already instantiated class at runtime), as opposed to object's class
and/or subclass. It is easy to add functionality to an entire class of objects by subclassing an object's class, but it is impossible to extend a single object this way. With the Decorator Pattern, you can add functionality to a single object and leave others like it unmodified.
In Java, a classical example of the decorator pattern is the Java I/O Streams implementation.
FileReader frdr = new FileReader(filename);
LineNumberReader lrdr = new LineNumberReader(frdr);
The preceding code creates a reader -- lrdr
-- that reads from a file and tracks line numbers. Line 1 creates a file reader (frdr
), and line 2 adds line-number tracking.
Actually, I'd highly encourage you to look at the Java source code for the Java I/O classes.
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.