深入浅出设计模式之装饰者设计模式

1.引子

假如有一家咖啡店想设计一个系统,他们是这样设计的。
这里写图片描述

他们设计了一个基类,把所有的产品继承这个基类,并复写他的cost方法。当要购买咖啡时,怎么得出咖啡的价格呢?需要知道咖啡加里的糖,摩卡,牛奶等等的物品的价格,这些物品也应该继承基类,实现cost方法,来计算价格。
表面上这个方法很符合我们平时的想法。但是……..

这里写图片描述
因此看来,这种设计会产生非常非常多的类,当然这样的设计是不合理的.

第二种设计方法:当然我们可以使用很少的类,设置一个基类,在基类里增加一些属性和方法,利用这些属性和方法来计算咖啡的价格,
这里写图片描述

这样我们只要用不同的咖啡类来继承基类,并覆盖cost方法来实现不同的咖啡类,就不会产生像第一种设计这么多类了。看起来这种设计很完美,但是也是有缺陷的,调节价格会使我们更改代码,出现新的调料也要更改代码。

装饰着模式可以很好的解决上述的问题

定义:

动态的将这人附加到对象上。若要扩展功能,装饰着提供了比继承着更有弹性的替代方案。
比如我们需要特制的深培咖啡:

  • 先创建一个深培咖啡(DarkRoast)对象
  • 以摩卡(Mocha)装饰他
  • 再用奶泡(Whip)装饰他
  • 调用最外圈装饰者Whip的cost();Whip调用Mocha的cost();Mocha调用DarkRoast的cost()

下面是装饰者模式的类结构:
这里写图片描述

现在把我们的咖啡店的咖啡也用这种模式所构建,以下是类图:
这里写图片描述

//抽象的基类
public abstract class Beverage{
    String description = "Unknown Beverage";
    public String getDescription(){
        return description;
    }
    public abstract double cost();
}

//抽象的调料类,也是装饰着类,继承了Beverage接口
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 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();
    }
}

.......用相同的方法制造其他的调料装饰者

//测试类
Beverage.Beverage beverage = new Beverage.Espresso();
Console.WriteLine(beverage.GetDescription() + " $ " + beverage.Cost());
Beverage.Beverage beverage1 = new Beverage.DarkRoase();
//用摩卡装饰
beverage1 = new Beverage.Mocha(beverage1);
//顾客要求双份摩卡
beverage1 = new Beverage.Mocha(beverage1);
//用奶泡装饰
beverage1 = new Beverage.Whip(beverage1);
//求出价格
Console.WriteLine(beverage1.GetDescription() + " $ " + beverage1.Cost());

jdk中的装饰类

在jdk中用到了很多这种设计模式,比如最典型的是io类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值