CS 4773 Object Oriented Systems The Decorator Pattern
This material is from Chapter 17 of the Design Patterns Explained book.
- From the Gang of Four:
The intent of the Decorator Pattern is to attach additional
responsibilities to an object dynamically.
Decorators private a flexible alternative to subclassing for
extending functionality.
- The Concrete Component is the class that we want to add
functionality to.
Example: Java input (See Core Java, Chapter 12)
Consider a FileInputStream which is used to read from a file.
This is the concrete component.
Here are some decorators that can be added to any InputStream:
- BufferedInputStream which adds buffering to any
InputStream.
Input streams are not buffered by default,
and they contact the file system on each read.
Adding buffering can increase efficiency.
- DataInputStream adds the capability of reading things other
than bytes, such as double, int, String, etc.
- PushbackInputStream gives the ability to unread something
so you can peek into the input stream.
Example: Efficiently read complex types:
DataInputStream din = new DataInputStream(
new BufferedInputStream)
new FileInputStream("myfile")));
Example: Be able to peek into a buffered input stream:
PushbackInputStream pbin = new PushbackInputStream(
new BufferedInputStream(
new FileInputStream("myfile")));
If you also want to be able to read complex types then also do:
DataInputStream din = new DataInputStream(pbin);
The advantage of these decorators is that they can be applied to any
InputStream.
All of the decorates also produce an InputStream
so they can be chained.
Since there are at least 8 different inputStreams and 9
decorators, we would need 72 classes if we used inheritance and this
would just give one level of chaining.
For 2 levels we would have over 600 classes.
Another example:
Add a button at the bottom of a JPanel: (note that this is not in Java)
The constructor might look like:
public ButtonJPanel extends JPanel(JPanel p, String s);
Makes a new panel with a button with label s at the bottom.
You can then make a panel with a stack of buttons ont he bottom by chaining
these together.
Of course, this may not be the best way to get this effect.
Another example:
The BorderFactory (this one is in Java).
It allows you to chain together borders for any JComponent to make borders
inside borders.