alexpdh's blog

Java设计模式(二十一):职责链模式

职责链模式(Chain Of Responsibility Pattern)

职责链模式(Chain Of Responsibility Pattern):属于对象的行为模式。使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。


职责链模式UML图

chain-of-responsibility-pattern.jpg


职责链模式涉及的角色

抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
具体处理者(ConcreteHandler)角色:处理它所负责的请求,由于持有对下家的引用,所以可以访问它的后继者,如果可以处理该请求,就处理之,否则将该请求转发给它的后继者。


示例代码

抽象处理者 Handler

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
package com.example.chainOfResponsebilityPattern;
/**
* 职责链模式:抽象处理者
*
* 定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。
* 这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,
* 抽象方法handleRequest()规范了子类处理请求的操作。
*
* @author pengdh
* @date: 2017-08-12 14:05
*/
public abstract class Handler {
protected Handler successor;
/**
* 持有对下家的引用
*/
public void setSuccessor(Handler successor) {
this.successor = successor;
}
/**
* 请求处理
*/
protected abstract void handlerRequest(int request);
}

具体处理者类 A ConcreteHandlerA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.chainOfResponsebilityPattern;
/**
* 职责链模式:具体处理者类 A
*
* 处理它所负责的请求,由于持有对下家的引用,所以可以访问它的后继者,
* 如果可以处理该请求,就处理之,否则将该请求转发给它的后继者。
*
* @author pengdh
* @date: 2017-08-12 14:10
*/
public class ConcreteHandlerA extends Handler {
@Override
protected void handlerRequest(int request) {
if (request >= 0 && request < 10) {
System.out.println("处理 0-10 请求");
} else {
successor.handlerRequest(request); // 转移到后继者类处理
}
}
}

具体处理者类 B ConcreteHandlerB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.chainOfResponsebilityPattern;
/**
* 职责链模式:具体处理者类 B
*
* 处理它所负责的请求,由于持有对下家的引用,所以可以访问它的后继者,
* 如果可以处理该请求,就处理之,否则将该请求转发给它的后继者。
*
* @author pengdh
* @date: 2017-08-12 14:17
*/
public class ConcreteHandlerB extends Handler {
@Override
protected void handlerRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println("处理 10-20 的请求");
} else {
successor.handlerRequest(request); // 转移到后继者类处理
}
}
}

客户端测试类 ChainOfResponsibilityPatternTest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.chainOfResponsebilityPattern;
/**
* 职责链模式:客户端测试类
*
* @author pengdh
* @date: 2017-08-12 14:21
*/
public class ChainOfResponsibilityPatternTest {
public static void main(String[] args) {
Handler h1 = new ConcreteHandlerA();
Handler h2 = new ConcreteHandlerB();
// 持有一个对后继者的引用
h1.setSuccessor(h2);
int[] arrays = {1, 15, 3, 11};
for (int request : arrays) {
h1.handlerRequest(request);
}
}
}

职责链模式的优点

客户端提交请求后,请求是沿着链传递直到有一个具体处理者对象处理它,这样做的好处是客户端可以不用管请求由哪个对象来处理。这使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构,结构是职责链可以简化对象的相互连接,它们只需保持一个对后继者的引用,而不需要保持它的所有候选接收者。从而大大降低了耦合度。但是也要注意的是职责链模式的具体处理是有末端的,也就是说会有请求得不到处理的情况,所以客户端在发送请求的时候需要注意是否有对应的具体处理者不能处理的情况。


参考文献

alexpdh wechat
欢迎扫一扫关注 程序猿pdh 公众号!