decorator
play

Decorator Intent Dynamically attach additional responsibilities to - PowerPoint PPT Presentation

Decorator Pattern CS356 Object-Oriented Design and Programming http://cs356.yusun.io November 7, 2014 Yu Sun, Ph.D. http://yusun.io yusun@csupomona.edu Decorator Intent Dynamically attach additional responsibilities to an object


  1. Decorator Pattern CS356 Object-Oriented Design and Programming http://cs356.yusun.io November 7, 2014 Yu Sun, Ph.D. http://yusun.io yusun@csupomona.edu

  2. Decorator ¿ Intent ¿ Dynamically attach additional responsibilities to an object ¿ Provide a flexible alternative to subclassing (static) ¿ Decorating object is transparent to the core component ¿ Also Known As – Wrapper

  3. Motivation ¿ We want to add different kinds of borders and/or scrollbars to a TextView GUI component ¿ Borders – Plain, 3D, or Fancy ¿ Scrollbars – Horizontal and/or Vertical

  4. Motivation ¿ An inheritance solution requires 15 subclasses to represent each type of view 1. TextView-Plain 9. TextView-Plain-Horizontal-Vertical 2. TextView-3D 10. TextView-3D-Horizontal 3. TextView-Fancy 11. TextView-3D-Vertical 4. TextView-Horizontal 12. TextView-3D-Horizontal-Vertical 5. TextView-Vertical 13. TextView-Fancy-Horizontal 6. TextView-Horizontal-Vertical 14. TextView-Fancy-Vertical 7. TextView-Plain-Horizontal 15. TextView-Fancy-Horizontal-Vertical 8. TextView-Plain-Vertical

  5. Solution 1: Use Object Composition TextView border scrollbar Border Scrollbar PlainBorder 3DBorder FancyBorder Horizontal Vertical Horizontal Scrollbar Scrollbar Vertical Scrollbar ¿ Is it Open-Closed? ¿ Can you add new features without affecting TextView? ¿ e.g., what about adding sound to a TextView?

  6. Decorator Pattern Solution VisualComponent TextView VisualDecorator component Border Scrollbar PlainBorder 3DBorder FancyBorder Horizontal Vertical Horizontal Scrollbar Scrollbar Vertical Scrollbar ¿ Change the Skin, not the Guts! ¿ TextView has no borders or scrollbars! ¿ Add borders and scrollbars on top of a TextView

  7. Structure What is significance of this? Component component ConcreteComponent Decorator Operation() Operation() Component->Operation(); ConcreteDecoratorA ConcreteDecoratorB Operation() Operation() Decorator::Operation(); AddedBehavior() AddBehavior(); addedState The decorator forwards requests to the component and may perform additional actions (such as drawing a border) before or after any forwarding

  8. Component u Defines the interface for objects that can have responsibilities added dynamically Component component ConcreteComponent Decorator Operation() Operation() Component->Operation(); ConcreteDecoratorA ConcreteDecoratorB Operation() Operation() Decorator::Operation(); AddedBehavior() AddBehavior(); addedState

  9. ConcreteComponent u The "base" object to which additional responsibilities can be added Component component ConcreteComponent Decorator Operation() Operation() Component->Operation(); ConcreteDecoratorA ConcreteDecoratorB Operation() Operation() Decorator::Operation(); AddedBehavior() AddBehavior(); addedState

  10. Decorator u Maintains a reference to a Component object u Defines an interface conformant to Component's interface Component component ConcreteComponent Decorator Operation() Operation() Component->Operation(); ConcreteDecoratorA ConcreteDecoratorB Operation() Operation() Decorator::Operation(); AddedBehavior() AddBehavior(); addedState

  11. ConcreteDecorator u Adds responsibilities to the component Component component ConcreteComponent Decorator Operation() Operation() Component->Operation(); ConcreteDecoratorA ConcreteDecoratorB Operation() Operation() Decorator::Operation(); AddedBehavior() AddBehavior(); addedState

  12. Decorator ¿ Applicability ¿ Dynamically and transparently attach responsibilities to objects ¿ Responsibilities that can be withdrawn ¿ Extension by subclassing is impractical ¿ May lead to too many subclasses

  13. Example – Sales Ticket Printing

  14. Example: Decorate Sales Ticket Printing ¿ Assume the SalesTicket currently creates an html sales receipt for an Airline Ticket ¿ New Requirements ¿ Add header with company name ¿ Add footer that is an advertisement ¿ During the holidays add holiday relevant header(s) and footer(s) ¿ We ’ re not sure how many such things ¿ One solution ¿ Place control in SalesTicket ¿ Then you need flags to control what header(s) get printed

  15. Decorator Approach ¿ A layered approach ¿ Start chain with decorators ¿ End with original object Decorator Decorator Concrete 1 2 Component

  16. Example – Sales Ticket Printing Component SalesOrder printTicket() printTicket() main(String[]) SalesTicket TicketDecorator Configuration printTicket() TicketDecorator(Component) printTicket() getSalesTicket() component FooterDecorator1 HeaderDecorator1 FooterDecorator1(Component) HeaderDecorator1(Component) printTicket() printTicket() printFooter() printHeader() FooterDecorator2 HeaderDecorator2 FooterDecorator2(Component) HeaderDecorator2(Component) printTicket() printTicket() printFooter() printHeader()

  17. A SalesTicket Implementation Component SalesOrder printTicket() printTicket() main(String[]) // Instances of this class are the sales tickets SalesTicket TicketDecorator // that may be decorated Configuration printTicket() TicketDecorator(Component) public class SalesTicket extends Component { printTicket() getSalesTicket() public void printTicket() { component // Hard coded here, but simpler than // adding a new Customer class now System.out.println("Customer: Bob"); FooterDecorator1 HeaderDecorator1 System.out.println("The sales ticket itself"); System.out.println("Total: $123.45"); FooterDecorator1(Component) HeaderDecorator1(Component) printTicket() printTicket() } printFooter() printHeader() } FooterDecorator2 HeaderDecorator2 FooterDecorator2(Component) HeaderDecorator2(Component) printTicket() printTicket() printFooter() printHeader()

  18. TicketDecorator Component SalesOrder printTicket() printTicket() main(String[]) SalesTicket TicketDecorator Configuration printTicket() TicketDecorator(Component) printTicket() getSalesTicket() component public abstract class TicketDecorator extends Component { private Component component; FooterDecorator1 HeaderDecorator1 public TicketDecorator(Component c) { FooterDecorator1(Component) HeaderDecorator1(Component) printTicket() component = c; printTicket() printFooter() printHeader() } FooterDecorator2 HeaderDecorator2 public void printTicket() { if(component != null) FooterDecorator2(Component) HeaderDecorator2(Component) component.printTicket(); printTicket() printTicket() printFooter() } printHeader() }

  19. A Header Decorator Component public class HeaderDecorator1 extends TicketDecorator { SalesOrder printTicket() public HeaderDecorator1(Component c) { printTicket() main(String[]) super(c); } SalesTicket TicketDecorator public void printTicket() { Configuration printTicket() TicketDecorator(Component) this.printHeader(); printTicket() super.printTicket(); getSalesTicket() } component public void printHeader() { System.out.println("@@ Header One @@"); FooterDecorator1 HeaderDecorator1 } } FooterDecorator1(Component) HeaderDecorator1(Component) printTicket() printTicket() printFooter() printHeader() FooterDecorator2 HeaderDecorator2 FooterDecorator2(Component) HeaderDecorator2(Component) printTicket() printTicket() printFooter() printHeader()

  20. Example – Sales Ticket Printing Component public class FooterDecorator2 extends TicketDecorator { SalesOrder printTicket() printTicket() public FooterDecorator2(Component c) { main(String[]) super(c); } SalesTicket TicketDecorator public void printTicket() { Configuration printTicket() TicketDecorator(Component) super.printTicket(); printTicket() getSalesTicket() this.printFooter(); component } public void printFooter() { System.out.println("## FOOTER Two ##"); FooterDecorator1 HeaderDecorator1 } FooterDecorator1(Component) HeaderDecorator1(Component) } printTicket() printTicket() printFooter() printHeader() FooterDecorator2 HeaderDecorator2 FooterDecorator2(Component) HeaderDecorator2(Component) printTicket() printTicket() printFooter() printHeader()

  21. SalesOrder (Client) Component SalesOrder printTicket() printTicket() public class SalesOrder { main(String[]) public static void main(String[] args) { SalesOrder s = new SalesOrder(); SalesTicket TicketDecorator s.printTicket(); Configuration printTicket() TicketDecorator(Component) } printTicket() getSalesTicket() public void printTicket() { component // Get an object decorated dynamically Component myST = Configuration.getSalesTicket(); myST.printTicket(); FooterDecorator1 HeaderDecorator1 } FooterDecorator1(Component) HeaderDecorator1(Component) printTicket() printTicket() // calcSalesTax ... printFooter() printHeader() } FooterDecorator2 HeaderDecorator2 FooterDecorator2(Component) HeaderDecorator2(Component) printTicket() printTicket() printFooter() printHeader()

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend