您现在的位置是:首页 >技术杂谈 >设计模式--装饰者模式网站首页技术杂谈
设计模式--装饰者模式
简介设计模式--装饰者模式
问题
星巴克可乐订单
(1) 可乐种类/单品可乐 :BaiShiCola(百事可乐) FeiChangCola(非常可乐) CoCola(可口可乐)
(2) 调料/附品: Milk Chocolate
(3) 要求在扩展新的可乐种类时 要具有良好的扩展性 改动方便 维护方便
(4) 使用OO的来就算不同之类可乐的费用 客户可以点单品可乐 也可以单品可乐+调料组合
方案1
(1) drink是一个抽象类 表示饮料
(2) des是对可乐的描述 比如可乐的名字
(3) cost()方法就是计算费用 drink类中为一个抽象方法
(4) Cola就是单品可乐 继承drink 并实现cost()
(5) CoCola&&Milk就是单品可乐+调料 这个组合很多
(6) 问题:这样设计 会有很多类 当我们增加一个单品可乐 或者一个新的调料 类的数量就会倍增 会出现类爆炸
方案2
前面分析的方案1因为可乐单品+调料组合会造成类的倍增 因此可以做改进 将调料内置到Drink类 这样就不会造成类数量过多 从而提高项目的可维护性
说明: milk cholocate可以设计为Boolean 表示是否要添加相应的调料
(1) 方案2 可以控制类的数量 不至于造成很多的类
(2) 在增加或者删除调料种类时 代码的维护量很大
(3) 考虑到用具可以添加多份调料时 可以将 hasMilk返回对应的int
(4) 使用 装饰者模式
基本介绍
装饰者模式 :动态的将新功能附加到对象上 在对象功能扩展方面 它比继承更有弹性 装饰者模式体现了开闭原则(OCP)
代码举例
书写抽象Drink
@Data
public abstract class Drink {
private String des; //描述
private float price = 0.0f;
/**
* 计算费用的抽象方法
* 具体细节子类来实现
* @return
*/
abstract float cost();
}
单品可乐
public class Cola extends Drink {
@Override
float cost() {
return getPrice();//调用父类抽象方法
}
}
具体可乐实现 百事可乐
public class BaiShiCola extends Cola{
public BaiShiCola(){
setPrice(4.0f);
setDes("百事==>"+getPrice()); //父类方法
}
}
具体可乐实现 可口可乐
public class CoCola extends Cola{
public CoCola(){
setPrice(3.0f);
setDes("可口可乐==>"+getPrice()); //父类方法
}
}
具体可乐实现 非常可乐
public class FeiChangCola extends Cola {
public FeiChangCola() {
setPrice(2.0f);
setDes("非常可乐==>"+getPrice()); //父类方法
}
}
装饰器
public class Decorator extends Drink{
private Drink drink;
Decorator(Drink drink){//组合
this.drink = drink;
}
@Override
float cost() {
//getPrice 本身价格
return getPrice()+drink.cost();
}
@Override
public String getDes() {
//drink.getDes() 输出被装饰者信息
return super.getDes()+"==>"+getPrice()+"&&"+drink.getDes();
}
@Override
public float getPrice() {
return super.getPrice();
}
}
具体的装饰 巧克力
//具体的装饰 巧克力
public class Chocolate extends Decorator {
Chocolate(Drink drink){
super(drink);
setDes("巧克力");
setPrice(3.0f);//调味品的价格
}
}
具体的装饰 牛奶
public class Milk extends Decorator {
Milk(Drink drink){
super(drink);
setDes("牛奶");
setPrice(5.0f);//调味品的价格
}
}
测试
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。