Attach additional responsibilities or functions to an object dynamically or statically. Also known as Wrapper.
A JScrollPane object can be used to decorate a JTextArea object or a JEditorPane object. A window can be decorated with different borders like BevelBorder, CompoundBorder, EtchedBorder TitledBorder etc. These border classes working as decorators are provided in Java API.
Decorator pattern can be used in a non-visual fashion. For example, BufferedInputStream, DataInputStream, and CheckedInputStream are decorating objects of FilterInputStream class. These decorators are standard Java API classes.
To illustrate a simple decorator pattern in non-visual manner, we design a class that prints a number. We create a decorator class that adds a text to the Number object to indicate that such number is a random number. Of course we can subclass the Number class to achieve the same goal. But the decorator pattern provides us an alternative way.
import java.util.Random; class Number { public void print() { System.out.println(new Random().nextInt()); } } class Decorator { public Decorator() { System.out.print("Random number: ");//add a description to the number printed new Number().print(); } } class SubNumber extends Number{ public SubNumber() { super(); System.out.print("Random number: "); print(); } } class Test { public static void main(String[] args) { new Decorator(); new SubNumber(); } }
C:\> java Test Random number: 145265744 Random number: 145265755 |
Recap: The Number class just produces a random number. We use Decorator and SubNumber classes to attach or add a description to the random number which is produced by Number class. This is how Decorator pattern works.