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

来源:互联网 发布:生鲜网络销售平台 编辑:程序博客网 时间:2024/05/29 06:59

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