目录
装饰器模式(Decorator Pattern)
概述
所属:结构型模式,作为现有的类的一个包装。
适用时机:扩展某个类的时候。不使用子类继承的方式,避免继承带来的子类膨胀。
优点:
- 不改变原来类的结构。
- 与原来类解耦合。
实现
原本接口 interface A,有许多实现类,比如 class A1、class A2。为了拓展 A1、A2 的功能,需要准备一个抽象装饰类 abstract class ADecorator,封装原本接口 interface A(这里就需要将 A 作为 ADecorator 的实例变量,这样 ADecorator 的实现类就可以调用 A 原本的方法)。通过实现抽象装饰类 ADecorator ,来扩展功能。
示例代码如下:
public interface A {
void call();
}
public class A1 implements A {
@Override
public void call() {
System.out.println("I'm A1.");
}
}
public class A2 implements A {
@Override
public void call() {
System.out.println("I'm A2.");
}
}
现在我们首先需要一个抽象装饰类 ADecorator 来封装 A,然后在 ADecorator 的具体实现类 ExtenedADecorator 中扩展其功能:
public abstract class ADecorator implements A {
protected A decoratedA;
public ADecorator(A decoratedA){
this.decoratedA = decoratedA;
}
public void call(){
decoratedA.call();
}
}
public class ExtenedADecorator extends ADecorator {
public ExtenedADecorator(A decoratedA) {
super(decoratedA);
}
@Override
public void call() {
// 在这里拓展,可以直接写在该方法中,这里的扩展示例为调用 extendedMethod(decoratedA);
decoratedA.call();
extendedMethod(decoratedA);
}
private void extendedMethod(A decoratedA){
System.out.println("I'm extendedMethod.");
}
}
那么我们就可以对原来的 A1、A2 进行装饰,调用装饰类方法:
public class DecoratorPatternDemo {
public static void main(String[] args) {
A a1 = new A1();
A a2 = new A2();
// 原本调用 call 方法
a1.call();
a2.call();
// 使用装饰类
// 1.装饰原本类
ADecorator extenedA1 = new ExtenedADecorator(a1);
ADecorator extenedA2 = new ExtenedADecorator(a1);
// 2.调用扩展方法
extenedA1.call();
extenedA2.call();
}
}
业界实践
在Java中,大部分集合是非线程安全的,然而,在 java.util.Colletions 中,实现了 Synchronized 相关类,装饰非线程安全的 java.util.Colletion 实现类,将其包装为线程安全的实现类。
Colletions 中,SynchronizedCollection 为抽象装饰类装饰接口 Colletion:
而对应的 Synchronized 类作为拓展类,拓展了线程安全的功能。如 SynchronizedSet: