美文网首页
装饰器模式

装饰器模式

作者: 阳光的技术小栈 | 来源:发表于2018-01-22 15:12 被阅读7次

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

示例—咖啡店

因为扩张速度实在太快了,他们准备更新订单系统,以合乎他们的饮料供应要求。
Beverage(饮料)是一个现有抽象类,店内所提供的饮料都必须继承自此类。Beverage包括一个description属性、getDescription实例方法、抽象方法cost等等。
购买咖啡时,也可以要求在其中加入各种调料,例如:蒸奶(Steamed Milk)、豆浆(Soy)、摩卡(Mocha,也就是巧克力风味)或覆盖奶泡。他们会根据所加入的调料收取不同的费用。所以订单系统必须考虑到这些调料部分。

UML图表示

咖啡店的装饰器模式设计

代码演示


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

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

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

/**
 * 浓缩咖啡
 */
class Espresso extends Beverage {

    public Espresso(){
        description = "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}

/**
 * 混合咖啡
 */
class HouseBlend extends Beverage {

    public HouseBlend(){
        description = "House Blend Coffee";
    }

    @Override
    public double cost() {
        return .89;
    }
}

/**
 * 深烘焙咖啡
 */
class DarkRoast extends Beverage {

    public DarkRoast(){
        description = "Dark Roast Coffee";
    }

    @Override
    public double cost() {
        return .99;
    }
}

/**
 * 低咖啡因咖啡
 */
class Decaf extends Beverage {

    public Decaf(){
        description = "Decaf Coffee";
    }

    @Override
    public double cost() {
        return 1.05;
    }
}

/**
 * 摩卡
 */
class Mocha extends CondimentDecorator{

    Beverage beverage;

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

    @Override
    public double cost() {
        return .20 + beverage.cost();
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }
}

/**
 * 牛奶
 */
class Milk extends CondimentDecorator{

    Beverage beverage;

    public Milk(Beverage beverage){
        this.beverage = beverage;
    }

    @Override
    public double cost() {
        return .10 + beverage.cost();
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Milk";
    }
}

/**
 *  豆浆
 */
class Soy extends CondimentDecorator{

    Beverage beverage;

    public Soy(Beverage beverage){
        this.beverage = beverage;
    }

    @Override
    public double cost() {
        return .15 + beverage.cost();
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Soy";
    }
}

/**
 *  奶泡
 */
class Whip extends CondimentDecorator{

    Beverage beverage;

    public Whip(Beverage beverage){
        this.beverage = beverage;
    }

    @Override
    public double cost() {
        return .10 + beverage.cost();
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Whip";
    }
}

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());

        Beverage beverage3 = new HouseBlend();
        beverage3 = new Soy(beverage3);
        beverage3 = new Mocha(beverage3);
        beverage3 = new Whip(beverage3);
        System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
    }
}

测试结果

Espresso $1.99
Dark Roast Coffee, Mocha, Mocha, Whip $1.49
House Blend Coffee, Soy, Mocha, Whip $1.34

相关文章

网友评论

      本文标题:装饰器模式

      本文链接:https://www.haomeiwen.com/subject/vfpiixtx.html