设计模式之装饰着模式
-
简单例子说明装饰者模式
-
星巴克咖啡订单项目(咖啡管)
-
咖啡种类:Espresso(意大利浓咖啡)、shortBlack、LongBlack、Decaf
-
调料:Milk、Chicilate、Soy(豆浆)
-
要求在扩展新的咖啡时,具有良好的延展性、改动方便、维护方便
-
使用OO来计算不同种类咖啡的费用:用户可以点单品咖啡,也可以单品+调料组合
-
-
实施方案
-
方案一(不推荐)
-
类图
-
分析
-
Drink是一个抽象类,表示饮料
-
des就是对咖啡的描述,比如咖啡封顶名字,价格等等
-
cost()就是计算费用,在Drink是一个抽象方法
-
单品咖啡继承了Drink
-
Espress && Milk就是单品咖啡+调料。这种组合很多
-
-
缺点:
-
这样设计时,当我们增加一个新非咖啡种类或者调料时,类的数量机会倍增,就会出现类爆炸
-
-
-
方案二(比方案一好一些)
-
上面在方案一分析出,如果使用方案一会发生类爆炸,因此方案二进行了改进,将调料内置到Drink,这样就不会造成类的数量过多,从而提高项目的维护性
-
类图
-
分析
-
方案二可以控制类的数量,不至于造成很多的类
-
在增加或者删除调料种类时,代码的维护量还是很大
-
考虑到用户可以添加多份调料时,可以将hasXXX()返回一个int
-
考虑使用装饰者模模式
-
-
-
-
-
通过装饰者模式解决上面两种解决方案的不足、
-
装饰者模式定义
-
装饰者模式:动态的将新功能附加到对象上,在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则
-
这里提到的动态的将新功能附加到对象和ocp原则,在代码会会得以体现
-
-
装饰者模式原理
-
说明
-
实现图
-
代码实现
//注意分包
//编写Drink,这是一个比较重要的类
public abstract class Drink{
public String des;//对Drink的描述
private float price = 0.0f;
//增加get和set方法
//计算 费用的抽象方法
public abstract float cost();
}
//编写coffee类
public class Coffee extends Drink{
@Iverride
public float cost(){
super.getPrice();
}
}
//编写具体的咖啡种类
public class Espresso extends Coffee{
public Espresso(){
setDes("意大利浓咖啡");
setPrice(6.0f);
}
}
//其他咖啡参考Espresso来写就可以了
//装饰者
public class Decorator extend Drink{
private Drink obj;
public Decorator(Drink obj){
this.obj =obj;
}
@Override
public float cost(){
return super.getPrice() + obj.cost();
}
@Override
public String getDes(){
//obj.getDes()输出被装饰者的信息
return super.des + " " + super.getPrice() + " && " +obj.getDes();
}
}
//编写调味品的信息
// 巧克力
public class Chocolate extends Decorator{
public Chocolate(Drink obj){
super(obj);
setDes("巧克力");
//设置当前调味品的价格
setprice(3.0f);
}
}
//其他的调味品参考巧克力
//下订单
public class CoffeeBar{
public static void main(String[] args){
//下订单:2分巧克力+一份牛奶的LongBlack,补全调味品
//步骤1:点一份被装饰者
Drink order = new LongBalck();
System.out.println("费用1 = "+order.cost());
//步骤2:加入一份牛奶
order = new Milk(order);
//步骤3:加入一份巧克力
order = new Chocolate(order);
//步骤4:在加入一份巧乐力
order = new Chocolate(order);
System.out.println("描述 = "+order.getDes());
System.out.println("费用 = "+order.cost());
}
} -
装饰者模式在JDK应用中的源码
-
java的I/o结构,FilterInputStream就是一个装饰者
-
代码
-
-
-
-