👉文章示例代码👈
装饰器模式对于笔者来说,印象还是比较深刻的。因为当年笔者考软件设计师的设计模式大题考的就是这个模式,差点阵亡。
定义
动态地为一个对象添加一些额外的职责。
在扩展原有对象功能上,装饰器模式比继承的方式更加灵活。
模式中的角色
- 抽象构建(Component):定义一个抽象接口(可以是抽象类),用以给对象动态地添加职责。
- 具体构建(ConcreteComponent):定义一个具体的对象,实现Component接口。
- 抽象装饰者(Decorator):继承Component,用有Component的职责,同时也可以扩展职责。
- 具体装饰者(ConcretorDecorator):负责给具体的构建对象添加职责,同时可以定义额外的职责。
场景示例
笔者作为一点点的重度爱好者,这里就以奶茶为例。
创建抽象构建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
public abstract class AbstractMilkyTea {
protected abstract String desc();
protected abstract int price(); }
|
创建具体构建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
public class MilkyTea extends AbstractMilkyTea {
@Override protected String desc() { return "奶茶"; }
@Override protected int price() { return 7; } }
|
创建抽象装饰者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
public abstract class AbstractDecorator extends AbstractMilkyTea {
private AbstractMilkyTea abstractMilkyTea;
public AbstractDecorator(AbstractMilkyTea abstractMilkyTea) { this.abstractMilkyTea = abstractMilkyTea; }
@Override protected String desc() { return this.abstractMilkyTea.desc(); }
@Override protected int price() { return this.abstractMilkyTea.price(); } }
|
这里抽象装饰者继承了抽象奶茶类。
这个时候,具体奶茶类和抽象装饰者类都作为抽象奶茶类的子类。
我们可以通过具体奶茶类和抽象装饰者类继承的父类(抽象奶茶类)进行组合让这两个子类建立关系。
创建具体装饰者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
public class SugarDecorator extends AbstractDecorator {
public SugarDecorator(AbstractMilkyTea abstractMilkyTea) { super(abstractMilkyTea); }
@Override protected String desc() { return super.desc() + " 加糖"; }
@Override protected int price() { return super.price() + 1; } }
public class RedBeanDecorator extends AbstractDecorator {
public RedBeanDecorator(AbstractMilkyTea abstractMilkyTea) { super(abstractMilkyTea); }
@Override protected String desc() { return super.desc() + " 加红豆"; }
@Override protected int price() { return super.price() + 2; } }
public class PearlDecorator extends AbstractDecorator {
public PearlDecorator(AbstractMilkyTea abstractMilkyTea) { super(abstractMilkyTea); }
@Override protected String desc() { return super.desc() + " 加珍珠"; }
@Override protected int price() { return super.price() + 2; } }
|
测试类及输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
public class Test {
public static void main(String[] args) { AbstractMilkyTea abstractMilkyTea = new MilkyTea(); abstractMilkyTea = new SugarDecorator(abstractMilkyTea); abstractMilkyTea = new PearlDecorator(abstractMilkyTea); System.out.println(abstractMilkyTea.desc() + " 的销售价格是:" + abstractMilkyTea.price());
abstractMilkyTea = new MilkyTea(); abstractMilkyTea = new RedBeanDecorator(abstractMilkyTea); abstractMilkyTea = new PearlDecorator(abstractMilkyTea); System.out.println(abstractMilkyTea.desc() + " 的销售价格是:" + abstractMilkyTea.price()); } }
|
测试类输出的结果如下:
奶茶 加糖 加珍珠 的销售价格是:10
奶茶 加红豆 加珍珠 的销售价格是:11
类结构图
以上示例类的结构图如下所示

总结
适用场景
- 给一个类添加额外的职责
- 动态的为一个对象添加功能同时可以动态撤销
优点
- 比继承更加灵活,易扩展。可以在不改变原有对象的情况下给一个对象扩展功能。
- 解耦。装饰类和被装饰者可以独立变化,不会相互耦合。
缺点
会导致代码和类的骤增,增加程序复杂性。
参考