装饰者模式
业务需求:
- 星巴克咖啡项目:单品咖啡,可以选择添加调料
- 咖啡种类:意大利、美式、无因、shortBlack
- 调料:牛奶、豆浆、巧克力
- 要求,扩展新的品类的咖啡,具有良好扩展性,改动方便,维护方便
- 用面向对象的思想计算不同咖啡的费用,客户可以单点咖啡,也可以咖啡+调料
方案一分析:
- Drink抽象类表示饮料,des是咖啡描述(名字),cost是计算费用(抽象方法)
- 咖啡+调料的组合很多,产生很多的类;每增加一个咖啡或调料,类的数量就会倍增,出现类爆炸
方案二分析:
- 方案二可以控制类的数量,不至于造成过多的类
- 增加或删除调料中类时,代码维护量仍然很大;
- 考虑到用户可以添加多份调料时,可以将has方法返回对应的int,比第一个方案略好,仍然不完美
- 可以考虑使用装饰者模式
装饰者模式定义
- 装饰者模式:动态的将新功能附加到对象上,,在对象功能扩展方面,他比继承更有弹性,装饰者模式也体现了开闭原则
需求设计方案
说明
- Drink类是抽象类
- ShortBlack是单品咖啡,Coffee是缓冲层
- Decorator是装饰类,需要含有一个被装饰的对象(Drink obj)
- Decorator的cost方法进行费用的叠加计算,递归计算价格
- milk包含了longblack
- 一份longblack包含了milk+longblack
- 一份chocolate包含了milk+longblack+chocolate
- 不论什么形式的单品咖啡+调料组合,通过递归的方式便可以组合和维护
代码实现
Drink父类
@Data
public abstract class Drink {
public String des;// 描述
private float price;// 价格
// 计费
public abstract float cost();
}
Coffee缓冲层
public class Coffee extends Drink {
@Override
public float cost() {
return super.getPrice();
}
}
具体咖啡类
public class Espresso extends Coffee {
public Espresso() {
setDes("意大利咖啡")