|
The Decorator Pattern
An Introduction with Examples in Java |
|
Prof. David Bernstein |
| Computer Science Department |
| bernstdh@jmu.edu |
/**
* Prints text to the console
*
* @author Prof. David Bernstein, James Madison University
* @version 1.0
*/
public class ConsolePrinter implements Printer
{
/**
* Print the given String
*
* @param text The String to print
*/
public void print(String text)
{
System.out.print(text);
}
}
/**
* An abstract decorator of Printer
*
* @author Prof. David Bernstein, James Madison University
* @version 1.0
*/
public abstract class PrinterDecorator implements Printer
{
protected Printer decorated;
/**
* Explicit Value Constructor
*
* @param decorated The Printer to decorate
*/
public PrinterDecorator(Printer decorated)
{
this.decorated = decorated;
}
/**
* Print the given String
* (required by Printer)
*
* @param text The String to print
*/
public void print(String text)
{
decorated.print(text);
}
}
/**
* A Printer that always prints in uppercase
*
* @author Prof. David Bernstein, James Madison University
* @version 1.0
*/
public class UppercasePrinter extends PrinterDecorator
{
/**
* Explicit Value Constructor
*
* @param decorated The Printer to decorate
*/
public UppercasePrinter(Printer decorated)
{
super(decorated);
}
/**
* Print the given String
* (required by Printer)
*
* @param text The String to print
*/
public void print(String text)
{
decorated.print(text.toUpperCase());
}
}
import java.util.*;
/**
* A Printer that wraps at word boundaries
*
* @author Prof. David Bernstein, James Madison University
* @version 1.0
*/
public class WrappingPrinter extends PrinterDecorator
{
protected int width;
/**
* Explicit Value Constructor
*
* @param decorated The Printer to decorate
* @param width The maximum width
*/
public WrappingPrinter(Printer decorated, int width)
{
super(decorated);
this.width = width;
}
/**
* Print the given String
* (required by Printer)
*
* @param text The String to print
*/
public void print(String text)
{
int required, used;
String token;
StringTokenizer st;
st = new StringTokenizer(text);
used = 0;
while (st.hasMoreTokens())
{
token = st.nextToken();
required = token.length();
if ((required + used + 1) > width)
{
decorated.print("\n");
decorated.print(token);
used = required + 1;
}
else
{
if (used != 0)
{
decorated.print(" ");
++used;
}
decorated.print(token);
used += required;
}
}
}
}
/**
* An application that demonstrates the use of the
* Decorator Pattern
*
* @author Prof. David Bernstein, James Madison University
* @version 1.0
*/
public class Driver
{
/**
* The entry point
*
* @param args The command line arguments
*/
public static void main(String[] args)
{
Printer printer;
String text;
text = "This is the text that we will use " +
"to demonstrate the capabilities " +
"of different Printer objects.";
printer = new ConsolePrinter();
printer.print(text);
System.out.print("\n\n");
printer = new UppercasePrinter(new ConsolePrinter());
printer.print(text);
System.out.print("\n\n");
printer = new WrappingPrinter(new ConsolePrinter(), 20);
printer.print(text);
System.out.print("\n\n");
printer = new WrappingPrinter(
new UppercasePrinter(
new ConsolePrinter()), 20);
printer.print(text);
}
}
An Example