概念
动态地给对象添加一些额外的职责。就功能来说装饰模式比生成子类更为灵活。
在许多设计中,可能需要改进类的某个对象的功能,而不是该类创建的全部对象。例如,麻雀类的实例能连续飞行100米,如果用麻雀类创建5只麻雀,那么这5只麻雀都能连续飞行100米。假如想让其中一只麻雀能连续飞行150米,那我们应当怎么做呢?我们不想通过修改麻雀类的代码(也可能根本不允许修改)使得麻雀类创建的麻雀能够连续飞行150米。一种比较好的方法就是给麻雀装上智能电子翅膀。智能电子翅膀可以使得麻雀不使用自己的翅膀就能飞行50米。
装饰模式是动态地扩展一个对象的功能,而不需要改变原始类代码的一种成熟的设计模式。在装饰模式中,“具体组件”类和“具体装饰”类是该模式中最重要的两个角色。“具体组件”类的实例称作“被装饰者”,“具体装饰”类的实例称作“装饰者”。“具体装饰”类需要包含有“具体组件”类的一个实例的引用,以便装饰“被装饰者”。
例如,前面所述的麻雀类就是“具体组件”类,而一只麻雀就是“具体组件”类的一个实例,即是一个“被装饰者”,而安装了电子翅膀的麻雀就是“具体装饰”类的一个实例,即安装了电子翅膀的麻雀是麻雀的“装饰者”。
结构与使用
装饰模式的结构中包含四种角色。
抽象组件(Component):抽象组件是一个抽象类。抽象组件定义了“被装饰者”需要进行“装饰”的方法。
具体组件(ConcreteCommponent):具体组件是抽象组件的一个子类,具体组件的实例称作“被装饰者”。
装饰(Decorator):装饰也是抽象组件的一个子类,但装饰还包括抽象组件申明的变量以保存“被装饰者”的引用。装饰可以使抽象类也可以是非抽象类,如果是非抽象类,它的实例称作“装饰者”。
具体装饰(ConcreteDecorator):具体装饰是装饰的一个非抽象子类,具体装饰的实例称作“装饰者”。
UML类图

结构的描述
1.抽象组件
本问题中,抽象组件规定了具体组件需要实现的方法。
1 | public abstract class Bird { |
2.具体组件
具体组件是Sparrow类。
1 | public class Sparrow extends Bird { |
3.装饰
1 | public abstract class Decorator extends Bird{ |
4.具体装饰
1 | public class SparrowDecorator extends Decorator { |
5.测试程序
1 | public class Application { |
使用多个装饰者
由于装饰是抽象组件的一个子类,因此“装饰者”本身也可作为一个“被装饰者”,这意味着可以使用多个具体装饰类来装饰具体组件的实例。
比如,对于上面的小问题,假如我们不仅需要飞行150米、200米的鸟,而且需要飞行120米、170米、220米的鸟,这是我们只需再添加一个具体装饰即可。
1 | public class SparrowDecoratorTwo extends Decorator{ |
优点
被装饰者和装饰者是松耦合关系,由于装饰(Decorator)仅仅依赖于抽象的组件(Component),因此具体装饰只知道他要装饰的对象是抽象组件某一个子类的实例,但不需要知道是哪一个具体子类。
装饰模式满足“开-闭原则”。不必修改具体组件,就可以增加新的针对该具体组件的装饰。
可以使用多个具体装饰来装饰具体组件的实例。