《HeadFirst设计模式》二、装饰者模式

一、要点

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

开放-关闭原则 : 对扩展开放,对修改关闭。

现在有了开放-关闭原则引导我们。我们会努力地设计系统,好让关闭的部分和新扩展的部分隔离。

在这里插入图片描述
在这里插入图片描述

下面是装饰者模式的一个设计图:
仔细看。
之后的星巴兹饮料实例,都是基于这种模型,具体演进过去的。
在这里插入图片描述

星巴兹咖啡的例子。
这里基础的饮料就是Component,而调料就是具体的 Decorator。
在这里插入图片描述

在开始动手写代码实现星巴兹咖啡之前,有一个值得思考的问题。
装饰者模式,是为了动态地为对象赋予新的行为。

书中回想了下继承:


在一开始使用继承,去重写父类时其实也可以实现这个功能,但是因为继承有个弊端,如果有新的需求免不了改动类得代码。这很让人头疼,因为在继承很多层得情况下,父类得改动,会波及到所有子类。
所以,我们急需一种方法,解决继承这种静态赋予行为得方式。


而装饰者模式,就是用来在运行时,动态得赋予对象新行为得。

但是,在上面得设计蓝图中,你还是会发现有继承得存在。比如 Decorator 居然继承了 Component。它不是装饰者类嘛,为什么要和组件扯上关系。

书中回答:

装饰者和被装饰者必须是一样的类型,也就是有共同的超类,这是相当关键的地方。
在这里,我们利用继承达到“类型匹配”,而不是利用继承获得“行为”
在这里插入图片描述

二、代码

如果有一张单子点的是:“双倍摩卡豆浆奶泡拿铁咖啡”,请使用菜单得到正确的价钱并画一个图来表达
你的设计
在这里插入图片描述
Component组件

public abstract class Beverage {
    String description = "这是 Component 抽象类";


    public String getDescription() {
        return description;
    }


    public abstract  double cost();
}

装饰者抽象类

//首先,必须让Condiment Decorator能够取代Beverage,所以将CondimentDecorator扩展自 Beverage 类。
public abstract class CondimentDecorator extends Beverage {

    //所有的调料装饰者都必须重写 getDescription()方法。稍后我们会解释为什么
    public abstract String getDescription();
}

具体得基础饮料

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

    public Espresso() {
        //实例化时自动设置当前对象得描述,注意:description实例变量继承自Beverage
        this.description = "浓缩咖啡";
    }

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

public class HouseBlend extends Beverage {

    public HouseBlend() {
        //实例化时自动设置当前对象得描述,注意:description实例变量继承自Beverage
        this.description = "综合咖啡";
    }

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

public class DarkRoast extends Beverage {

    public DarkRoast() {
        //实例化时自动设置当前对象得描述,注意:description实例变量继承自Beverage
        this.description = "深焙咖啡";
    }

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

具体得调料

//调料
public class Mocha extends CondimentDecorator {

    Beverage beverage;

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

    @Override
    public String getDescription() {
        return beverage.getDescription() + "+摩卡";
    }

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

public class Soy extends CondimentDecorator {
    Beverage beverage;

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

    @Override
    public String getDescription() {
        return beverage.getDescription() + " +豆浆";
    }

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

测试代码

  public static void main(String[] args) {
        Beverage beverage = new HouseBlend();


        beverage = new Mocha(beverage);
        beverage = new Mocha(beverage);
        beverage = new Soy(beverage);


        System.out.println(beverage.getDescription());
        System.out.println(beverage.cost());
    }
综合咖啡+摩卡+摩卡 +豆浆
1.44

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_popo_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值