读《HeadFirst设计模式》笔记之装饰者模式

装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。java

特色:this

  • 装饰者和被装饰对象有相同的超类型。
  • 你能够用一个或多个装饰者包装一个对象。
  • 既然装饰者和被装饰对象有相同的超类型,因此在任何须要原始对象(被包装的)的场合,能够用装饰过的对象代替它。
  • 装饰者能够在所委托被装饰者的行为以前与/或以后,加上本身的行为,以达到特定的目的。
  • 对象能够在任什么时候候被装饰,因此能够在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。

 举个栗子:设计

领导给你分配设计一个咖啡收款系统。咖啡能够加配料,不一样的配料收费不一样。怎么设计一个灵活的系统呢?思考三秒钟3d

若是一个顾客想要摩卡(Mocha)和奶泡(Whip)深焙咖啡(DarkRoast),使用装饰者模式怎么作呢?code

一、以DarkRoast对象开始对象

二、顾客想要摩卡(Mocha),因此创建一个Mocha对象,并用它将DarkRoast对象包(wrap)起来。blog

三、顾客也想要奶泡(Whip),因此须要创建一个Whip装饰者,并用它将Mocha对象包起来。别忘了,DarkRoast继承自Beverage,且有一个cost()方法,用来计算饮料价钱。继承

四、如今,该是为顾客算钱的时候了。经过调用最外圈装饰者(Whip)的cost()就能够办获得。Whip的cost()会先委托它装饰的对象(也就是Mocha)计算出价钱,而后再加上奶泡的价钱。ip

 

代码实现:get

咖啡抽象类:

public abstract class Beverage {
    String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

配料抽象类,继承咖啡抽象类:

public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}

咖啡的实现:

// 浓咖啡
public class Espresso extends Beverage {
    public Espresso() {
        description = "Espresso";
    }

    public double cost() {
        return 1.99;
    }
}

// 深焙咖啡
public class DarkRoas extends Beverage {
    public DarkRoas () {
        description = "Dark Roas Coffee";
    }

    public double cost() {
        return 0.89;
    }
}

配料实现:

public class Mocha extends CondimentDecorator {
    Beverage beverage;
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }
    public double cost() {
        return 0.20 + beverage.cost();
    }
}

来一杯咖啡:

public class StarbuzzCoffee {
    public static void main(String args[]) {
        // 一杯不加配料的浓咖啡
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + ": $" + beverage.cost());

        // 双倍摩卡和奶泡深焙咖啡
        Beverage beverage2 = new DarkRoast();
        beverage2 = new Mocha(beverage2);
        beverage2 = new Mocha(beverage2);
        beverage2 = new Whip(beverage2);
        System.out.println(beverage2.getDescription() + ": $" + beverage2.cost());

        // 再来一杯调料为豆浆、摩卡、奶泡的HouseBlend咖啡
        Beverage beverage3 = new HouseBlend();
        beverage3 = new Soy(beverage3);
        beverage3 = new Mocha(beverage3);
        beverage3 = new Whip(beverage3);
        System.out.println(beverage3.getDescription() + ": $" + beverage3.cost());
    }
}

相关文章
相关标签/搜索