先给出一个情景:开发一个给人搭配不同服饰的系统
我们要考虑的
- 满足
开放封闭原则
- 不能每添加一种服饰就要做大量的修改
- 组装过程最好在类的内部,对外不可见
- 需要考虑组装的顺序
装饰模式UML图

如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类
针对模式原型的代码实现(Java)
Component接口
1 2 3
| public interface Component { public abstract void Operation(); }
|
Component实现类
1 2 3 4 5 6
| public class ConceteComponent implements Component { @Override public void Operation() { System.out.println("具体对象的操作"); } }
|
具体Component类
1 2 3 4 5 6 7 8
| public class ConcreteDecoratorA extends Decorator {
@Override public void Operation() { super.Operation(); System.out.println("具体装饰对象A的操作"); } }
|
1 2 3 4 5 6 7 8
| public class ConcreteDecoratorB extends Decorator {
@Override public void Operation() { super.Operation(); System.out.println("具体装饰对象B的操作"); } }
|
装饰类
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Decorator implements Component { protected Component component; public void SetComponent(Component component) { this.component = component; }
@Override public void Operation() { if (component != null) { component.Operation(); } } }
|
客户端
1 2 3 4 5 6 7 8
| public static void main(String[] args) { ConceteComponent c = new ConceteComponent(); ConcreteDecoratorA d1 = new ConcreteDecoratorA(); ConcreteDecoratorB d2 = new ConcreteDecoratorB(); d1.SetComponent(c); d2.SetComponent(d1); d2.Operation(); }
|
针对情景的代码实现
人
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Person { public Person () {}
private String name; public Person(String name) { this.name = name; }
public void show() { System.out.println("装扮人是" + name); } }
|
衣服类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Finery extends Person { protected Person component; public void decorate(Person component) { this.component = component; }
@Override public void show() { if (component != null) { component.show(); } } }
|
具体衣服类
1 2 3 4 5 6 7 8
| public class Trouser extends Finery { @Override public void show() { System.out.println("垮裤"); super.show(); } }
|
1 2 3 4 5 6 7 8
| public class TShirts extends Finery { @Override public void show() { System.out.println("T恤"); super.show(); } }
|
客户端
1 2 3 4 5 6 7 8 9 10
| public static void main(String[] args) { Person xyy = new Person("xyy");
TShirts tShirts = new TShirts(); Trouser trouser = new Trouser();
tShirts.decorate(xyy); trouser.decorate(tShirts); trouser.show(); }
|
装扮模式的优势
动态地给一个对象添加一些额外地职责
将对象地实现和对象的使用分开
- 每个装饰对象只关心自己的功能,不需关心如何被添加到对象链中
- 为已有功能动态地添加更多功能
特定情况特殊行为
- 新加入地功能满足在某种特定情况才会执行的特殊行为
装饰模式的缺点
- 虽然扩展性较高,但是类的数量较多(若需求明确且后期发生变化概率不大,则没必要使用装饰模式)
- 很难知晓类被装饰了多少层
本文部分内容改编于程杰老师的《大话设计模式》