23种设计模式--装饰器模式
结构型设计模式的一种
【DP】定义
动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活
使用场景
- 已有功能只能满足部分需求,需要在已有功能基础上动态增加功能,使用装饰器可以将核心功能和装饰功能从逻辑上区分开
- 有一个动作执行链,需要指定先做什么,后做什么
类图
核心是装饰器继承已有功能接口,并使用已有功能接口,这样就可以实现按顺序装饰。
AbstractDecrator类是抽象类,根据需求选择是否需要该类。
举例
有一个场景: 平台部门写了公共打印的功能,但是业务部门A需要在打印前增加打印人,业务部门B除了要在打印前增加打印人,还需要在打印后增加打印时间。
公共打印接口和实现类如下:1
2
3
4
5
6
7
8
9
10public interface IPrint {
void print();
}
public class PlatformPrint implements IPrint {
public void print() {
System.out.println("Platform print......");
}
}
业务部门A需要给公共接口增加动作,那么A可以增加装饰器如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class APrint implements IPrint{
// 要装饰的对象
private IPrint print;
// 装饰动作
public void decorate(IPrint print) {
this.print = print;
}
public void print() {
// 打印前增加打印人
System.out.println("Printer: abcd");
// 执行被装饰对象的方法
print.print();
}
}
业务部门B也需要增加动作,但是可以在A的基础上增加即可,代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class BPrint implements IPrint {
// 要装饰的对象
private IPrint print;
// 装饰动作
public void decorate(IPrint print) {
this.print = print;
}
public void print() {
// 执行被装饰对象的方法
print.print();
// 打印后增加打印时间
System.out.println("Print time : 2019-04-02");
}
}
那么,在使用时,就可以如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class Main {
public static void main() {
// 平台打印
IPrint print = new PlatformPrint();
// 业务A打印
APrint aPrint = new APrint();
// 业务A装饰平台打印类
aPrint.decorate(print);
aPrint.print();
// 业务B打印
BPrint bPrint = new BPrint();
// 业务B装饰业务A打印类
bPrint.decorate(aPrint);
bPrint.print();
}
}
注意事项
- 装饰器的功能最好分开