Title: CS 350 Software Design The Decorator Pattern Chapter 17
1CS 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.
2CS 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.
3CS 350 Software DesignThe Decorator Pattern
Chapter 17
- Sales Order using SalesTicket with different
Options
4CS 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.
5CS 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.
6CS 350 Software DesignThe Decorator Pattern
Chapter 17
- Decorator Pattern Applied to E-Commerce Case
Study - The concrete decorators are the headers and
footers.
7CS 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
8CS 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 ()
9CS 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
10CS 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
-
11CS 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())))
12CS 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()))))
13CS 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()))))
14CS 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 objects
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.
15CS 350 Software DesignThe Decorator Pattern
Chapter 17
- Generic Structure of the Decorator Pattern