指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
装饰器模式的主要优点有:
其主要缺点是:装饰器模式会增加许多子类,过度使用会增加程序得复杂性。
装饰器模式主要包含以下角色。
装饰器模式的结构图如图:
装饰器模式的实现代码如下:
// 抽象构件角色 public interface Component { void operation(); } // 具体构件角色 public class ConcreteComponent implements Component{ public ConcreteComponent() { System.out.println("创建具体构件角色"); } @Override public void operation() { System.out.println("调用具体构件角色的方法operation()"); } } // 抽象装饰角色 public class Decorator implements Component{ private Component component; public Decorator(Component component) { this.component = component; } @Override public void operation() { component.operation(); } } // 具体装饰角色 public class ConcreteDecorator extends Decorator{ public ConcreteDecorator(Component component) { super(component); } @Override public void operation() { super.operation(); addedFunction(); } public void addedFunction() { System.out.println("为具体构件角色增加额外的功能addedFunction()"); } } // 测试类 public class Main { public static void main(String[] args) { Component component = new ConcreteComponent(); component.operation(); Component decorator = new ConcreteDecorator(component); decorator.operation(); } }
输出结果如下:
创建具体构件角色
调用具体构件角色的方法operation()
调用具体构件角色的方法operation()
为具体构件角色增加额外的功能addedFunction()
可以看到,使用装饰模式为具体构件角色增加了额外的功能,对其进行加强操作。
装饰器模式在 Java 语言中的最著名的应用莫过于 Java I/O 标准库的设计。
下面代码是为 FileReader 增加缓冲区而采用的装饰类 BufferedReader 的例子:
BufferedReader in = new BufferedReader(new FileReader("filename.txt")); String s = in.readLine();
装饰器模式所包含的 4 个角色不是任何时候都要存在的,在有些应用环境下模式是可以简化的,如以下两种情况。
(1) 如果只有一个具体构件而没有抽象构件时,可以让抽象装饰继承具体构件,其结构图如图:
(2) 如果只有一个具体装饰时,可以将抽象装饰和具体装饰合并,其结构图如图: