一,定义
动态的将新功能附加到对象上。在对新功能扩展方面,他比继承更具有弹性
装饰者模式也体现了开闭原则
顾名思义,装饰者模式就像一个包装一个快递一样的包装盒
二,以饮料为例,来讲解什么是装饰者模式
假设有一个饮料drink抽象类,实现coffee咖啡与不同点心的搭配问题,如上图。
以面向对象的思想。肯定是每个对象为一个类。假设每个人都是点一份咖啡和一些点心时。假设我们就以简单的组合的方式,那么就肯定有n种组合,并且根据种类的不同,以及份数的不同,就更加的增加了代码的臃肿性
接下来就需要使用到装饰者模式了,我们就将这个点心作为被装饰者,那么就只需要考虑点心了。因此给点心一个装饰类,比如需要一份咖啡和一份牛奶和一份巧克力,如下图,只需要层层包装即可
三,代码
drink类
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(); }
coffee类
public class Coffee extends Drink { @Override public float cost() { return super.getPrice(); } }
public class LongBlack extends Coffee { public LongBlack(){ setDes("美式咖啡"); setPrice(3.0f); } }
public class Espresso extends Coffee { public Espresso(){ setDes("意大利咖啡"); setPrice(6.0f); } }
装饰者类 Decorator 类
public class Decorator extends Drink { private Drink obj; public Decorator(Drink obj){ this.obj = obj; } @Override public float cost() { return super.getPrice() + obj.cost(); } @Override public String getDes() { return super.des + " " + super.getPrice()+ "&&" + obj.getDes(); } }
点心类
豆浆类 Soy
public class Soy extends Decorator { public Soy(Drink obj) { super(obj); setDes("豆浆"); setPrice(1.5f); } }
牛奶类 Milk
public class Milk extends Decorator { public Milk(Drink obj) { super(obj); setDes("牛奶"); setPrice(2.0f); } }
巧克力类 chocolate
public class Chocolate extends Decorator { public Chocolate(Drink obj) { super(obj); setDes("巧克力"); setPrice(3.0f); //调味品价格 } }
四,测试类 CofferBar
public class CofferBar { public static void main(String[] args) { //1,先点一份LongBlack Drink order = new LongBlack(); //费用一 System.out.println(order.cost()); //2,加入一份牛奶 order = new Milk(order); System.out.println(order.cost()); System.out.println(order.getDes()); //3,加入一份巧克力 order = new Chocolate(order); System.out.println(order.cost()); System.out.println(order.getDes()); } }
如图
这样的话就完美的解决了咖啡和点心的组合了。当然由于每个人是点一份咖啡和多份点心的,因此需要不同的咖啡就需要创建不同的的 coffee 对象即可了!