行为型设计模式的一种

【DP】定义

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止。

使用场景

  1. 一个请求的处理需要多个对象当中的一个或几个协作处理

类图

职责链模式

类图核心是:抽象处理类中的设置后继者的方法setSuccessor,并且后继者也是抽象处理类类型。这就产生了一种链式结构。

举例

假设有个请假的单据,自动审批类包括经理审批类、总经理审批类和CEO审批类,每个自动审批类的权限不同,经理审批类只有三天权限,总经理审批类有七天权限,CEO审批类有半个月权限。

对于这个请假单据的自动审批,就可以用职责链模式,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/**
* 请假单据类
*/
public class Voucher {
// 请假人
private String personName;
// 请假天数
private String leaveDayNum;
}

/**
* 自动审批抽象类
*/
public abstract class AbsApprove {
// 后继者
protected AbsApprove successor;
public void setSuccessor(AbsApprove successor) {
this.successor = successor;
}
public abstract void handle(Voucher voucher);
}
/**
* 经理自动审批类
*/
public class ManagerApprove extends AbsApprove {
@Override
public void handle(Voucher voucher) {
int leaveDayNum = voucher.getLeaveDayNum();
if (leaveDayNum <= 3) {
// approve this voucher
} else {
// 无权处理,交给下一个职责处理类
this.successor.handle(voucher);
}
}
}
/**
* 总经理自动审批类
*/
public class GMApprove extends AbsApprove {
@Override
public void handle(Voucher voucher) {
int leaveDayNum = voucher.getLeaveDayNum();
if (leaveDayNum <= 7) {
// approve this voucher
} else {
// 无权处理,交给下一个职责处理类
this.successor.handle(voucher);
}
}
}
/**
* CEO自动审批类
*/
public class CEOApprove extends AbsApprove {
@Override
public void handle(Voucher voucher) {
int leaveDayNum = voucher.getLeaveDayNum();
if (leaveDayNum <= 15) {
// approve this voucher
} else {
// reject this voucher
}
}
}

/**
* 客户端类
*/
public class Main {
public static void main() {
// 声明各个审批类,并制定职责链的下一级
AbsApprove manager = new ManagerApprove();
AbsApprove gm = new ManagerApprove();
AbsApprove ceo = new CEOApprove();
manager.setSuccessor(gm);
gm.setSuccessor(ceo);

Voucher voucher = new Voucher("zhangsan", 20);
// 初始时交给经理来处理
manager.handle(voucher);
}
}

可以看到,客户端可以指定每个职责类的下一级是谁,然后将任务交给最初的职责类处理,不用管最后是谁处理的。

注意事项

  1. 重点理解两个词:“职责”和“链”,使用这种模式的时候要看各个类能否区分职责,并且是一个链式结构;
  2. 因为客户端可以随意指定职责类的下一级,因此可以实现越级处理的目的。