您的位置:首页 > 其它

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

2016-08-03 20:00 232 查看

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类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息