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

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