装饰者模式(decorator pattern): 动态地将责任附加到对象上, 若要扩展功能, 装饰者提供了比继承更有弹性的替代方案。
装饰者模式的详解
装饰者模式一对客户透明的方式动态地给一个对象附加上更多的责任。换而言之,客户端并不会觉得在装饰前后有什么不同。装饰者模式可以在不使 用创造更多子类的情况下,将对象的功能加以扩展。
类图:
角色说明:
抽象构件角色(Component):给一个抽象接口,以规范准备接受附加责任的对象。
具体构件角色(ConcreteComponent):定义一个将要接收附加责任的类。
装饰者角色(Decorator):持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
具体装饰者角色(ConcreteDecorator):负责给构件对象“贴上”附加的责任。
代码演示,抽象构建类:
public interface Component {
//一个简单操作的功能
public void sampleOperation();
}
具体构件类:
public class ConcreteComponent implements Component {
@Override
public void sampleOperation() {
System.out.println("这是具体构件角色的sampleOperation()方法");
}
}
装饰者类:
public class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void sampleOperation() {
// 委派给具体构件
component.sampleOperation();
}
}
具体装饰者类A:
public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
@Override
public void sampleOperation() {
super.sampleOperation();
System.out.println("这是具体装饰者角色A的sampleOperation()方法");
}
}
具体装饰者类B:
public class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}
@Override
public void sampleOperation() {
super.sampleOperation();
System.out.println("这是具体装饰者角色B的sampleOperation()方法");
}
}
客户端测试类:
public class Test {
public static void main(String[] args) {
Component concreteComponent = new ConcreteComponent();
Component concreteDecoratorA = new ConcreteDecoratorA(concreteComponent);
Component concreteDecoratorB = new ConcreteDecoratorB(concreteDecoratorA);
concreteDecoratorA.sampleOperation();
System.out.println("=================");
concreteDecoratorB.sampleOperation();
//也可以这样实现
// Component concreteDecoratorB = new ConcreteDecoratorB(new ConcreteDecoratorA(new ConcreteComponent()));
// concreteDecoratorB.sampleOperation();
}
}
运行结果:
ConcreteComponent类是具体构件类,而ConcreteDecoratorA和ConcreteDecoratorB是具体装饰者类,要装饰的正是具体构件类ConcreteComponent。
上面的运行结果可以看出把具体构件类ConcreteComponent装饰成具体装饰类ConcreteDecoratorA,输出的正是具体构件类和具体装饰类A的sampleOperation()方法(把具体装饰类A的功能附加到具体构件类中)。而后又把具体装饰类A装饰成具体装饰类B(就把装饰类B的功能附加到装饰类A中,得到的是具体构件类、具体装饰类A和具体装饰类B的功能,正如等号下面的输出一样)。
装饰者模式的优点:
- 装饰者模式和继承关系都是为了扩展对象的功能,但是装饰者模式比继承关系可以更加的灵活。装饰者模式可以动态的附加上一个需要的“装饰”,或是摘除掉一个不需要的“装饰”。但是继承是静态的,在系统运行前就决定了。
- 通过使用不同的具体装饰类以及它们的不同排列组合,程序员可以创造出很多不同行为的组合。
缺点:
- 从设计上,装饰者模式会比继承关系使用较少的类,这样使得设计比较容易。但是在使用上,装饰者模式会比继承关系产生更多的类,这样就会相对的消耗内存,影响性能,在具体装饰类名称相似时,还加大排查错误的难度。