目录
基本介绍
概述:动态的给对象增加一些职责,即增加其额外的功能。
特点:
- 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
- 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
- 装饰器模式完全遵守开闭原则
缺点:装饰器模式会增加许多子类,过度使用会增加程序得复杂性。
结构
抽象构件(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
本文详细介绍了装饰器模式,一种用于在不修改原有对象的基础上动态添加功能的设计模式。文章通过一个咖啡店的例子展示了如何使用装饰器模式来为饮品添加调料,如巧克力、牛奶和豆浆,以此实现不同组合的费用计算。装饰器模式是继承的补充,提供了更加灵活的扩展性,遵循开闭原则,但过度使用可能导致复杂性增加。

754





