职责链模式

职责链模式

定义

避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

类图

代码示例

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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
package com.zhaoyangwoo.chainOfResponsibility;
/**
* Created by john on 16/6/16.
* 职责链模式,经费审批场景
*/
public class Responsibility {
public static void main(String[] args) {
//zhaoyanghoo报销100元
Request request = new Request();
request.setName("zhaoyanghoo");
request.setLevel(new Level(100));
ApprovalUtil.handleApproval(request).print();
//zhaoyanghoo报销100元
Request request2 = new Request();
request2.setName("xiaohong");
request2.setLevel(new Level(10000));
ApprovalUtil.handleApproval(request2).print();
//zhaoyanghoo报销100元
Request request3 = new Request();
request3.setName("xiaoming");
request3.setLevel(new Level(10000000));
ApprovalUtil.handleApproval(request3).print();
}
}
/**
* 用这个工具类封装内部关系,client只需要知道ApprovalUtil,而不需要跟manage/director等关联
*/
class ApprovalUtil {
static Approval manage, director, cfo;
static {
manage = new Manager();
director = new Director();
cfo = new CFO();
manage.setSuccessor(director);
director.setSuccessor(cfo);
}
static Response handleApproval(Request request) {
return manage.handleApproval(request);
}
}
/**
* 抽象类,审批人
*/
abstract class Approval {
public void setSuccessor(Approval successor) {
this.successor = successor;
}
protected abstract Level getLevel();
//后继审批人
protected Approval successor;
public final Response handleApproval(Request request) {
if (request == null || request.getLevel() == null) return null;
if (this.getLevel() != null && this.getLevel().higherThen(request.getLevel())) {
return this.hanlder(request);
} else if (this.successor != null) {
return this.successor.handleApproval(request);
} else
return new Response("无人能处理" + request.getName() + "的报销请求");
}
protected abstract Response hanlder(Request request);
}
/**
* 经理只审批500元内经费
*/
class Manager extends Approval {
//最多审批500元
private final static Level level = new Level(500);
@Override
protected Level getLevel() {
return level;
}
@Override
public Response hanlder(Request request) {
return new Response(String.format("经理审批了%s的%d元报销", request.getName(), request.getLevel().getAmount()));
}
}
/**
* 总监审批1000元内的报销
*/
class Director extends Approval {
//最多审批1000元
private final static Level level = new Level(1000);
@Override
protected Level getLevel() {
return level;
}
@Override
public Response hanlder(Request request) {
return new Response(String.format("总监审批了%s的%d元报销", request.getName(), request.getLevel().getAmount()));
}
}
/**
* CFO审批100000
*/
class CFO extends Approval {
//最多审批500元
private final static Level level = new Level(100000);
@Override
protected Level getLevel() {
return level;
}
@Override
public Response hanlder(Request request) {
return new Response(String.format("CFO审批了%s的%d元报销", request.getName(), request.getLevel().getAmount()));
}
}
//请求模拟类
class Request {
public Level getLevel() {
return level;
}
public void setLevel(Level level) {
this.level = level;
}
//请求的级别
Level level;
//姓名
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//请求级别类
class Level {
public Level(int amount) {
this.amount = amount;
}
public int getAmount() {
return amount;
}
//报销金额
private final int amount;
//如果高于当前金额,则无法处理
public boolean higherThen(Object obj) {
if (obj == null) return false;
if (obj == this) {
return true;
} else if (obj instanceof Level) {
return this.amount > ((Level) obj).amount;
}
return false;
}
}
//相应模拟类
class Response {
public Response(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
//审批结果
private String message;
//打印审批结果
public void print() {
System.out.println(message);
}
}
```
### 应用场景举例
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
- 可动态指定一组对象处理请求
### JDK源码中的模式实现
`java.util.logging.Logger`类应用了责任链模式
```java
public void log(LogRecord record) {
if (!isLoggable(record.getLevel())) {
return;
}
Filter theFilter = filter;
if (theFilter != null && !theFilter.isLoggable(record)) {
return;
}
// Post the LogRecord to all our Handlers, and then to
// our parents' handlers, all the way up the tree.
Logger logger = this;
while (logger != null) {
final Handler[] loggerHandlers = isSystemLogger
? logger.accessCheckedHandlers()
: logger.getHandlers();
for (Handler handler : loggerHandlers) {
handler.publish(record);
}
final boolean useParentHdls = isSystemLogger
? logger.useParentHandlers
: logger.getUseParentHandlers();
if (!useParentHdls) {
break;
}
logger = isSystemLogger ? logger.parent : logger.getParent();
}
}
public boolean isLoggable(Level level) {
if (level.intValue() < levelValue || levelValue == offValue) {
return false;
}
return true;
}

思考

如何控制链的长度,以保证性能

可以在抽象类中添加一个static final的常量,标志最长的链有MAX个元素,一个static的set类型变量,setSuccessor方法中将handler添加到set变量中,比较MAX和Set.size()。

参考

  1. 《JAVA与模式》之责任链模式

  2. java.util.logging.Logger使用详解

作者: wuzhaoyang(John)
出处: http://wuzhaoyang.me/
因为作者水平有限,无法保证每句话都是对的,但能保证不复制粘贴,每句话经过推敲。希望能表达自己对于技术的态度,做一名优秀的软件工程师。