150 likes | 168 Views
Exploring the Decorator Pattern in enhancing Sales Ticket functionality with headers and footers dynamically. Learn how to extend object responsibilities flexibly.
E N D
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 In this chapter we expand our e-commerce case study and learn how to use the Decorator Pattern. The original solution showed how we could have a Sales order us the CalcTax object to compute the tax and a SalesTicket object to print the ticket.
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 However what happens if the sales ticket gets more complicated? We could add a header to the ticket. For that matter, we can add a footer to the ticket as well. A simple solution is to add flags to SalesTicket to determine whether or not I should print headers or footers. This is fine for a few simple options. If I have a option of printing one of many headers/footers at a time, I could implement a strategy to determine which header/footer to print. However, what if I have multiple headers and footers to print? Instead of having a control method to handle the added functionality, chain the functionality together in the order it is required. Separate the dynamic building of the chain of functionality from the client that uses it.
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 Sales Order using SalesTicket with different Options
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 The Decorator Pattern: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 The class diagram below implies the previously shown chain of objects. Each chain starts with a component (either a Concrete Component or a Decorator) Each Decorator is followed by another Decorator or by the original Concrete Component. The Concrete Component always ends the chain. Note that the Decorator and the Concrete Component must inherit from the same base class.
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 Decorator Pattern Applied to E-Commerce Case Study The concrete decorators are the headers and footers.
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 Decorator Code for E-Commerce Example //The client uses an abstract factory to create the objects needed public class Client { public static void main (String[] args) { Factory myFactory; myFactory = new Factory(); Component myComponent = myFactory.getComponent(); } } //The Component is the base class used to establish a common interface as well as allowing //both the Sales ticket and TicketDecorator to behave polymorphically. abstract public class Component { abstract public void prtTicket(); } abstract public class TicketDecorator extends Component { private Component myTrailer; public TicketDecorator (Component myComponent) { myTrailer=myComponent; } public void callTrailer () { if (myTrailer != null) myTrailer.prtTicket(); } }
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 Decorator Code for E-Commerce Example public class Header1 extends TicketDecorator { public Header1 (Component myComponent) { super (myComponent); } public void prtTicket () { //place printing header 1 code here super.callTrailer(); } } public class Header2 extends TicketDecorator { public Header2 (Component myComponent) { super (myComponent); } public void prtTicket () { //place printing header 2 code here super.callTrailer(); } }
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 Decorator Code for E-Commerce Example public class Footer1 extends TicketDecorator { public Footer1 (Component myComponent) { super (myComponent); } public void prtTicket() { super.callTrrailer(); //place printing footer 1 code here } } public class Footer2 extends TicketDecorator { public Footer2 (Component myComponent) { super (myComponent); } public void prtTicket() { super.callTrrailer(); //place printing footer 2 code here } }
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 Decorator Code for E-Commerce Example public class Factory { public Compnent getComponent () { Component myComponent; myComponent = new SalesTicket(); myComponent = new Footer1(myComponent); myCompoent = new Header1(myComponent); return myComponent; } }
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 If I want the sales ticket to look like: Header 1 Sales Ticket Footer 1 myFactory.getComponent returns: return (new Header1 (new Footer1 (new SalesTicket())));
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 If I want the sales ticket to look like: Header 1 Header 2 Sales Ticket Footer 1 myFactory.getComponent returns: return (new Header1 (new Header2 (new Footer1 (new SalesTicket()))));
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 If I want the sales ticket to look like: Header 1 Header 2 Sales Ticket Footer 1 myFactory.getComponent returns: return (new Header1 (new Header2 (new Footer1 (new SalesTicket()))));
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 Intent: Attach additional responsibilities to an object dynamically. Problem: The object that you want to use does not have the basic functions you require. However, you need to add additional functionality to the object that occurs before or after the object’s base functionality. Solution: Allow extending functionality of the object without resorting to subclassing by building a linked list of objects derived from the same base class. Implementation: Create an abstract class that represents both the original class and the new functions to be added to the class. In the decorators, place the new function calls before or after the trailing calls to get the correct order.
CS 350 – Software DesignThe Decorator Pattern – Chapter 17 Generic Structure of the Decorator Pattern