Unformatted text preview:

Decorator and FactoryKenneth M. AndersonUniversity of Colorado, BoulderCSCI 4448/6448 — Lecture 20 — 10/30/2008© University of Colorado, 2008Tuesday, November 4, 2008Lecture Goals• Cover Material from Chapters 3 and 4 of the Design Patterns Textbook• Decorator Pattern• Factory and Abstract Factory Pattern2Tuesday, November 4, 2008Decorator Pattern• The Decorator Pattern provides a powerful mechanism for adding new behaviors to an object at run-time• The mechanism is based on the notion of “wrapping” which is just a fancy way of saying “delegation” but with the added twist that the delegator and the delegate both implement the same interface• You start with object A that implements abstract type X• You then create object B that also implements abstract type X• You pass A into B’s constructor and then pass B to A’s client• The client thinks its talking to A but its actually talking to B• B’s methods augment A’s methods to provide new behavior3Tuesday, November 4, 2008Why? Open-Closed Principle• The decorator pattern provides yet another way in which a class’s runtime behavior can be extended without requiring modification to the class• This supports the goal of the open-closed principle:• Classes should be open for extension but closed to modification• Inheritance is one way to do this, but composition and delegation are more flexible (and Decorator takes advantage of delegation)• Chapter 3’s “Starbuzz Coffee” example clearly demonstrates why inheritance can get you into trouble and why delegation/composition provides greater run-time flexibility4Tuesday, November 4, 2008Starbuzz Coffee• Under pressure to update their “point of sale” system to keep up with their expanding set of beverage products• Started with a Beverage abstract base class and four implementations: HouseBlend, DarkRoast, Decaf, and Espresso• Each beverage can provide a description and compute its cost• But they also offer a range of condiments including: steamed milk, soy, and mocha•These condiments alter a beverage’s description and cost• “Alter” is a key word here since it provides a hint that we might be able to use the Decorator pattern5Tuesday, November 4, 2008Initial Starbuzz SystemgetDescription()cost()descriptionBeverage«Abstract»cost()HouseBlendcost()DarkRoastcost()Decafcost()EspressoWith inheritance on your brain, you may add condiments to this design in one of two ways1. One subclass per combination of condiment (wont work in general but especially not in Boulder!)2. Add condiment handling to the Beverage superclass6Tuesday, November 4, 2008One Subclass per CombinationgetDescription()cost()descriptionBeverage«Abstract»cost()HouseBlendcost()DarkRoastcost()Decafcost()Espressocost()HouseBlendWithSteamedMilkandMochacost()HouseBlendWithSoyandMochacost()EspressoWithSoyAndMochacost()DecafWithWhipandSoyThis is incomplete, but you can see the problem…(see page 81 for a more complete picture)7Tuesday, November 4, 2008Let Beverage Handle CondimentsgetDescription()hasMilk()setMilk()hasSoy()...cost()descriptionmilksoymochawhipBeverage«Abstract»cost()HouseBlendcost()DarkRoastcost()Decafcost()EspressoHouston, we have a problem…1. This assumes that all concrete Beverage classes need these condiments2. Condiments may vary (old ones go, new ones are added, price changes, etc.), shouldn’t they be encapsulated some how?3. How do you handle “double soy” drinks with boolean variables?8Tuesday, November 4, 2008Decorator Pattern: Definition and StructuremethodA()methodB()ComponentmethodA()methodB()...att1att2ConcreteComponentmethodA()methodB()DecoratormethodA()methodB()...ConcreteDecoratorAmethodA()methodB()...newatt1newatt2ConcreteDecoratorBcomponentInheritance is used to make sure that components and decorators share the same interface: namely the public interface of Component which is either an abstract class or an interfaceAt run-time, concrete decorators wrap concrete components and/or other concrete decoratorsThe object to be wrapped is typically passed in via the constructor9Tuesday, November 4, 2008Client PerspectiveConcreteDecoratorBConcreteDecoratorAClientConcreteComponentfoo()ConcreteComponentClientfoo() foo()foo()BEFOREAFTERIn both situations,Client thinks its talking toa Component. It shouldn’tknow about the concretesubclasses. Why?10Tuesday, November 4, 2008StarBuzz Using Decorators (Incomplete)getDescription()cost()Beveragecost()HouseBlendgetDescription()cost()CondimentDecoratorgetDescription()cost()MilkgetDescription()cost()Soybeverage11Tuesday, November 4, 2008Demonstration• Starbuzz Example• Use of Decorator Pattern in java.io package• InputStream == Component• FilterInputStream == Decorator• FileInputStream, StringBufferInputStream, etc. == ConcreteComponent• BufferedInputStream, LineNumberInputStream, etc. == ConcreteDecorator12Tuesday, November 4, 2008The Problem With “New”• Each time we invoke the “new” command to create a new object, we violate the “Code to an Interface” design principle• Example• Duck duck = new DecoyDuck()• Even though our variable’s type is set to an “interface”, in this case “Duck”, the class that contains this statement depends on “DecoyDuck”• In addition, if you have code that checks a few variables and instantiates a particular type of class based on the state of those variables, then the containing class depends on each referenced concrete classif (hunting) { return new DecoyDuck()} else { return new RubberDuck();}Obvious Problems: needs to be recompiled each time a dep. changes add new classes, change this code remove existing classes, change this codeThis means that this code violates the open-closed principle and the “encapsulate what varies” design principle13Tuesday, November 4, 2008PizzaStore Example• We have a pizza store program that wants to separate the process of creating a pizza with the process of preparing/ordering a pizza• Initial Code: mixed the two processespublic class PizzaStore {12 Pizza orderPizza(String type) {3 4 Pizza pizza;5 6 if (type.equals("cheese")) {7 pizza = new CheesePizza();8 } else if (type.equals("greek")) {9 pizza = new GreekPizza();10 } else if (type.equals("pepperoni")) {11 pizza = new PepperoniPizza();12 }13 14 pizza.prepare();15 pizza.bake();16 pizza.cut();17 pizza.box();18 19


View Full Document

CU-Boulder CSCI 6448 - Decorator and Factory

Documents in this Course
Struts

Struts

12 pages

Adapter

Adapter

23 pages

Prototype

Prototype

16 pages

Weka

Weka

15 pages

qooxdoo

qooxdoo

16 pages

Django

Django

12 pages

Overview

Overview

22 pages

XNA

XNA

5 pages

Load more
Download Decorator and Factory
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Decorator and Factory and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Decorator and Factory 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?