public class DecoratorClient { public static void main(String[] args) { DecoratorClient s = new DecoratorClient(); s.printTicket(); } public void printTicket() { // Get an object decorated dynamically Component myST = Configuration.getSalesTicket(); myST.printTicket(); } // calcSalesTax ... } abstract class Component { abstract public void printTicket(); } //Instances of this class are the sales tickets //that may be decorated class SalesTicket extends Component { @Override public void printTicket() { // Hard coded here, but simpler than // adding a new Customer class now System.out.println("Customer: Kim"); System.out.println("The sales ticket itself"); System.out.println("Total: $123.45"); } } abstract class TicketDecorator extends Component { private Component myComponent; public TicketDecorator() { myComponent = null; } public TicketDecorator(Component c) { myComponent = c; } @Override public void printTicket() { if (myComponent != null) myComponent.printTicket(); } } class HeaderDecorator1 extends TicketDecorator { public HeaderDecorator1(Component c) { super(c); } @Override public void printTicket() { this.printHeader(); super.printTicket(); } public void printHeader() { System.out.println("@@ Header One @@"); } } class FooterDecorator1 extends TicketDecorator { public FooterDecorator1(Component c) { super(c); } @Override public void printTicket() { super.printTicket(); this.printFooter(); } public void printFooter() { System.out.println("%% FOOTER one %%"); } } class HeaderDecorator2 extends TicketDecorator { public HeaderDecorator2(Component c) { super(c); } @Override public void printTicket() { this.printHeader(); super.printTicket(); } public void printHeader() { System.out.println(">> Header Two <<"); } } class FooterDecorator2 extends TicketDecorator { public FooterDecorator2(Component c) { super(c); } @Override public void printTicket() { super.printTicket(); this.printFooter(); } public void printFooter() { System.out.println("## FOOTER two ##"); } } //This object would determine how to decorate the SalesTicket. class Configuration { public static Component getSalesTicket() { // Return a decorated SalesTicket return new HeaderDecorator1( new HeaderDecorator2( new FooterDecorator2( new FooterDecorator1( new SalesTicket())))); } }