Previous Lecture Lecture 13 Next Lecture

Lecture 13, Wed 05/15

Design Patterns - Decorator

Decorator Pattern

Idea

PizzaDecorator

DecoratorUML

PizzaUMLDecorator

Implementation

/`/ Pizza.java
public abstract class Pizza {

    private String size = "";
    private String type = "";
    
    public String getSize() { return size; }
    public String getType() { return type; }
    public void setSize(String size) { this.size = size; }
    public void setType(String type) { this.type = type; }
    
    public abstract double cost();
}
// ToppingDecorator.java
public abstract class ToppingDecorator extends Pizza {
    public abstract String getType();
}
// Regular.java
public class Regular extends Pizza {

    public Regular(String size) {
        setSize(size);
        setType("Regular Crust");
    }
    
    @Override
    public double cost() {
        switch (getSize()) {
            case "small":
                return 10;
            case "medium":
                return 15;
            case "large":
                return 20;
        }
        return 0;
    }
}
// Pan.java
public class Pan extends Pizza {

    public Pan(String size) {
        setSize(size);
        setType("Pan Crust");
    }
    
    @Override
    public double cost() {
        switch (getSize()) {
            case "small":
                return 12;
            case "medium":
                return 17;
            case "large":
                return 22;
        }
        return 0;
    }
}
// Cheese.java
public class Cheese extends ToppingDecorator {
    
    private Pizza pizza;
    
    public Cheese(Pizza pizza) {
        this.pizza = pizza;
        setSize(pizza.getSize());
        setType(pizza.getType());
    }

    @Override
    public String getType() {
        return pizza.getType() + " + Cheese";
    }
    
    public double cost() {
        switch (pizza.getSize()) {
            case "small":
                return 1 + pizza.cost();
            case "medium":
                return 2 + pizza.cost();
            case "large":
                return 4 + pizza.cost();
        }
        return 0;
    }
}
// Pepperoni.java
public class Pepperoni extends ToppingDecorator {

    private Pizza pizza;
    
    public Pepperoni(Pizza pizza) {
        this.pizza = pizza;
        setSize(pizza.getSize());
        setType(pizza.getType());
    }

    @Override
    public String getType() {
        return pizza.getType() + " + Pepperoni";
    }
    
    public double cost() {
        switch (pizza.getSize()) {
            case "small":
                return 1.5 + pizza.cost();
            case "medium":
                return 2.5 + pizza.cost();
            case "large":
                return 4.5  + pizza.cost();
        }
        return 0;
    }
}
// Pineapple.java
public class Pineapple extends ToppingDecorator {

    private Pizza pizza;
    
    public Pineapple(Pizza pizza) {
        this.pizza = pizza;
        setSize(pizza.getSize());
        setType(pizza.getType());
    }

    @Override
    public String getType() {
        return pizza.getType() + " + Pineapple";
    }
    
    public double cost() {
        switch (pizza.getSize()) {
            case "small":
                return 0.75 + pizza.cost();
            case "medium":
                return 1.5 + pizza.cost();
            case "large":
                return 2.5 + pizza.cost();
        }
        return 0;
    }
}
// Lecture.java
public class Lecture {
    
    public static void printPizza(Pizza pizza) {
        System.out.format("%s %s: $%.2f\n", pizza.getSize(), pizza.getType(), pizza.cost());
        System.out.println("---");
    }
    
    public static void main(String[] args) {
        Pizza pizza = new Regular("large");
        pizza = new Cheese(pizza);
        pizza = new Pineapple(pizza);
        printPizza(pizza);
    
        Pizza pizza2 = new Pan("small");
        pizza2 = new Cheese(pizza2);
        pizza2 = new Cheese(pizza2);
        pizza2 = new Pepperoni(pizza2);
        printPizza(pizza2);	
    }
}