The Decorator Pattern
CSCI 3132 Summer 2011 1 Starbuzz Coffee
• Want to offer a variety of combina ons of coffee and condiments • Cost of a cup depends on the combina on that was ordered
2 First Design • Make a beverage class and a subclass for each legal combina on <
HouseBlend DarkRoast Decaf Espresso cost() cost() cost() cost() HouseBlendWith DecafWith EspressoWit SteamedMilk DarkRoastWith SteamedMilkSteamedMi l cost()HouseBlend SteamedMilk costDecaf() costEspresso() Mocha cost()DarkRoast Mocha Mocha HouseBlendcost() Mocha Decafcost () Espressocost() WithWhip DarkRoastcost() WithWhip WithWhip WithWhip cost() 3 cost() cost() 3 Problems with Inheritance
• Too many subclasses may be needed. • Need to define the implementa on of each subclass. • All classes inherit a sta c behaviour which may have to be overridden. • The inherited behaviour cannot be changed at run me, i.e. behaviour is sta c at run me. • Thus, the design is not flexible or maintainable.
4 Second Design
• Make the superclass contain booleans to specify which condiments are included and subclasses for each type of coffee • How do we compute cost? • What does it take to add a new condiment?
5 <
• Classes should be open for extension, but closed for modifica on – “extension” is NOT subclassing – It means the addi on of new behavior (without modifying the code!)
7 Decorator Pa ern
• Start with an instance of the “basic”classes and then decorate it with new capabili es
Whip Mocha Dark Roast
cost() cost() cost() 0.99 0.99+0.20 0.99+0.20+0.10
8 Key Points
• Decorators have the same supertypes as the objects they decorate – This lets us pass around the decorated object instead of the original (unwrapped) object • Decorator add behavior by delega ng to the object it decorates and then adding its own behavior • Can add decora ons at any me
9 Class Diagram for the Decorator Pa ern
10 Starbuzz Coffee Example
11 public abstract class Beverage{! String description = “Unknown”;!
public String getDescription() {! return description;! }!
public abstract double cost();! }! public abstract class CondimentDecorator extends Beverage {! public abstract String getDescription();! public abstract double cost();! }! public class Espresso extends Beverage {! public Espresso() {! description = “Espresso”; ! }!
public double cost() {! return 1.99;! }! }! 12 public class Mocha extends CondimentDecorator {! Beverage bev;!
public Mocha(Beverage bev) {! this.bev = bev;! }!
public String getDescription {! return bev.getDescription() + “, Mocha”;! }!
public double cost() {! return .20 + bev.cost();! }! }!
13 public class StarBuzz {! public static void main(String args[]) {! Beverage bev = new Espresso); ! bev = new Mocha(bev);! bev = new Mocha(bev);! bev = new Whip(bev);! bev = new Soy(bev);!
System.out.println(bev.getDescription() + “ $”+! bev.getCost()); ! }!
14 Decorators in Java
• File I/O Example
Concrete decorators
Component
BufferedInputStream LineNumberInputStream FileInputStream
15 Design Principle for the Decorator Pa ern
• Classes should be open for extension but closed for modifica on. • Systems can be extended without changing exis ng code. • Tradeoffs: – Takes me and effort. – Introduces new levels of abstrac on which makes designs more complicated and code hard to understand. • Due to the tradeoffs the decorator pa ern should not be used throughout the design but in areas that are most likely to change. • Experience and looking at other examples helps one determine which areas are likely to change.
16 Decorator Pa ern
• Provides a flexible alterna ve to using inheritance to extend func onality. • This achieved by introducing decorators that “decorate” objects. • Decorators have the same type as the objects they decorate. • An object can have one or more decorators.
17 The Decorator Pa ern
• The decorated object and the original object have the same type. Thus, the decorated object can be passed instead of the original object. • The decorator delegates part of its behaviour to the object it decorates. • It adds its own behaviour before or a er the delega on. • Objects can be delegated dynamically at run me. • The objects are “wrapped” with decorators. 18 Decorator Pa ern Summary
• Main design principle: Classes should be open for extension but closed for modifica on. • Achieves flexibility- behaviour can be extended without changing exis ng code. • Composi on and delega on is used to add new behaviours at run me. • A set of decorator classes are used to wrap concrete components. • Overuse of decorators can be complex as they can introduce a number of small objects into a design. 19