1、装饰者模式的定义
装饰者模式:动态的将新功能附加到对象上,在功能的扩展方面,他比继承更有弹性,装饰者模式也体现了开闭原则。
2 装饰者模式原理
1)装饰者模式就像打包一个快递
主体:陶瓷,衣服 //被装饰者
包装:报纸,塑料泡沫,纸板,木板 // 装饰者
2)Component:
主体:比如前面的饮料抽象类 Drink
3)ConcreteComponent 和 Decorator
ConcreteComponent : 具体的主体,比如前面的各个单品咖啡
Decorator:装饰者,比如各种调料
4)在如图的Component和ConcreteComponent 之间,如果ConcreteComponent 类还有很多
,还可以设计一个缓冲层吗,将共有的部分提取出来,抽象成一个类
3 装饰者模式解决星巴克咖啡订单问题
代码实现:
/** * @author houChen * @date 2020/9/29 8:51 * @Description: 被装饰类的抽象类 */ public abstract class Drink { public String des; //描述 private float price = 0.0f; public String getDes() { return des; } public void setDes(String des) { this.des = des; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } // 计算费用的抽象方法 //子类来实现 public abstract float cost(); }
/** * @author houChen * @date 2020/9/29 8:54 * @Description: 被装饰类和其具体子类之间的缓冲类 */ public class Coffee extends Drink{ @Override public float cost() { return super.getPrice(); } }
/** * @author houChen * @date 2020/9/29 8:58 * @Description: 被装饰类的具体类 */ public class LongBack extends Coffee{ public LongBack() { setDes("美式咖啡。。。"); setPrice(5.0f); } } public class Espresso extends Coffee { public Espresso() { setDes("意大利咖啡..."); setPrice(6.0f); } } public class ShortBack extends Coffee{ public ShortBack() { setDes("ShortBack。。。"); setPrice(4.0f); } }
/** * @author houChen * @date 2020/9/29 9:01 * @Description: 装饰者:装饰者中组装了被装饰者 */ public class Decorator extends Drink { //组合的关系 private Drink obj; public Decorator(Drink obj) { this.obj = obj; } @Override public float cost() { //getPrice():自己的价格 return super.getPrice()+obj.cost(); } @Override public String getDes() { return super.getDes()+""+super.getPrice()+"&&"+obj.getDes(); } } /** * @author houChen * @date 2020/9/29 9:09 * @Description: 具体的装饰者,在本例子中,表示的就是调味品 */ public class Chocolate extends Decorator { public Chocolate(Drink obj) { super(obj); setDes("巧克力"); setPrice(2.0f); //当前调味品的价格 } } public class Milk extends Decorator { public Milk(Drink obj) { super(obj); setDes("牛奶"); setPrice(3.0f); //当前调味品的价格 } } public class Soy extends Decorator{ public Soy(Drink obj) { super(obj); setDes("豆浆"); setPrice(3.0f); //当前调味品的价格 } }
/** * @author houChen * @date 2020/9/29 9:13 * @Description: 测试装饰者模式 */ public class Client { public static void main(String[] args) { // LongBack : 2份巧克力 + 一份牛奶 Drink drink = new LongBack(); drink = new Milk(drink); System.out.println("加入一份牛奶后 描述:"+drink.getDes()); System.out.println("加入一份牛奶后 费用:"+drink.cost()); System.out.println(); drink = new Chocolate(drink); System.out.println("加入一份牛奶后,又加入一份巧克力 描述:"+drink.getDes()); System.out.println("加入一份牛奶后,又加入一份巧克力 费用:"+drink.cost()); System.out.println(); drink = new Chocolate(drink); System.out.println("加入一份牛奶后,加入一份巧克力,再加入一份巧克力 描述:"+drink.getDes()); System.out.println("加入一份牛奶后,加入一份巧克力,再加入一份巧克力费用:"+drink.cost()); System.out.println(); } }