Template method
Wrappers are commonly used in:
The basic idea of a wrapper is to call-forward to an underlying object, while simultaneously allowing for new code to be executed just before and/or just after the call. Wrappers can be chained together, one after another. In this way, you can mix-and-match behaviors in various ways.
Note that this changes the behavior of an object, without needing to alter the implementation of a class, and also without needing to extend a class.
Here's an example implementation of a wrapper design pattern (other variations are also possible):
public interface TransformText { String render(String aInputText); }
/** Wrapper (Decorator) design pattern. */ public final class WrapperDemo { public static void main(String... aArgs){ TransformText transformer = new BaseWrapper(new Echo()); show(transformer.render("blah.")); // 'blah.' transformer = new Capitalize(new Echo()); show(transformer.render("blah.")); // 'BLAH.' transformer = new RemovePeriods(new Capitalize(new Echo())); show(transformer.render("blah.")); // 'BLAH' transformer = new RemovePeriods(new Echo()); show(transformer.render("blah.")); // 'blah' } private static void show(String aText){ System.out.println(aText); } private static final class Echo implements TransformText{ public String render(String aText) { return aText; } } /** This class both implements the interface AND is constructed with an implementation of the same interface. */ private static class BaseWrapper implements TransformText { BaseWrapper(TransformText aTransformText){ fShowText = aTransformText; } /** Template method, calls 'before' and 'after' methods. */ public final String render(String aText) { String text = before(aText); text = fShowText.render(text); //call-forward return after(text); } /** This default implementation does nothing.*/ String before(String aText){ return aText; } /** This default implementation does nothing.*/ String after(String aText){ return aText; } private TransformText fShowText; } private static final class Capitalize extends BaseWrapper { Capitalize(TransformText aTransformText){ super(aTransformText); } @Override String before(String aText) { String result = aText; if (aText != null){ result = result.toUpperCase(); } return result; } } private static final class RemovePeriods extends BaseWrapper { RemovePeriods(TransformText aTransformText){ super(aTransformText); } @Override String after(String aText) { String result = aText; if (aText != null){ result = result.replace(".", ""); } return result; } } }The output of this class is:
blah. BLAH. BLAH blah