目录
基本介绍
概述:动态的给对象增加一些职责,即增加其额外的功能。
特点:
- 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
- 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
- 装饰器模式完全遵守开闭原则
缺点:装饰器模式会增加许多子类,过度使用会增加程序得复杂性。
结构
抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
结构图
具体实现
结构图 |
//抽象类 (抽象构件) 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(); }
//咖啡类 public class Coffee extends Drink { @Override public float cost() { return super.getPrice(); } }
//具体的ShortBlack咖啡类 (具体构件) public class ShortBlack extends Coffee { public ShortBlack(){ setDes(" ShortBlack "); setPrice(4.0f); } }
//意大利咖啡类 (具体构件) public class Espresso extends Coffee { public Espresso(){ setDes("意大利咖啡"); setPrice(6); } }
//具体的LongBlack咖啡类 (具体构件) public class LongBlack extends Coffee { public LongBlack(){ setDes(" LongBlack "); setPrice(5); } }
//调味品类 (抽象装饰) 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() { //obj.getDes() 输出被装饰者的信息 return des + " " + super.getPrice() + " && " + obj.getDes(); } }
//具体的Decorator,这里就是调味品 (具体装饰) public class Chocolate extends Decorator { public Chocolate(Drink obj){ super(obj); setDes(" 巧克力 "); setPrice(3.0f); //调味品的价格 } }
//牛奶调味品类 (具体装饰) public class Milk extends Decorator{ public Milk(Drink obj) { super(obj); setDes(" 牛奶 "); setPrice(2.0f); } }
//豆浆调味品类 (具体装饰) public class Soy extends Decorator { public Soy(Drink obj) { super(obj); setDes(" 豆浆 "); setPrice(1.5f); } }
//测试类 public class CoffeeBar { public static void main(String[] args) { //装饰者模式下的订单:2份巧克力+一份牛奶的LongBlack //1.点一份LongBlack Drink order = new LongBlack(); System.out.println("费用1="+order.cost()); System.out.println("描述="+order.getDes()); //2.加入一份牛奶 order = new Milk(order); System.out.println("order 加入一份牛奶 费用="+order.cost()); System.out.println("order 加入一份牛奶 描述="+order.getDes()); //3.order加入一份巧克力 order = new Chocolate(order); System.out.println("order 加入一份牛奶 一份巧克力 费用="+order.cost()); System.out.println("order 加入一份牛奶 一份巧克力 描述="+order.getDes()); //4.order加入一份巧克力 order = new Chocolate(order); System.out.println("order 加入一份牛奶 2份巧克力 费用="+order.cost()); System.out.println("order 加入一份牛奶 2份巧克力 描述="+order.getDes()); } }
运行结果:
费用1=5.0
描述= LongBlack
order 加入一份牛奶 费用=7.0
order 加入一份牛奶 描述= 牛奶 2.0 && LongBlack
order 加入一份牛奶 一份巧克力 费用=10.0
order 加入一份牛奶 一份巧克力 描述= 巧克力 3.0 && 牛奶 2.0 && LongBlack
order 加入一份牛奶 2份巧克力 费用=13.0
order 加入一份牛奶 2份巧克力 描述= 巧克力 3.0 && 巧克力 3.0 && 牛奶 2.0 && LongBlack