责任链模式是一种行为设计模式,允许将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。职责链模式使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。
Chain-of-responsibility is a behavior design pattern that allows requests to be sent along the handler chain.
After receiving the request, each handler can process it or pass it on to the next handler on the chain.
Chain-of-responsibility pattern allows multiple objects to have the opportunity to process requests,
thereby avoiding coupling between the sender and receiver of requests.
结构设计
责任链会将特定行为转换为被称作处理者的独立对象。职责链模式建议将这些处理者连成一条链。链上的每个处理者都有一个成员变量来保存对于下一处理者的引用。除了处理请求外,处理者还负责沿着链传递请求。请求会在链上移动,直至所有处理者都有机会对其进行处理。注意,处理者可以决定不再沿着链传递请求,这可高效地取消所有后续处理步骤。
责任链模式包含如下角色:
Handler是抽象处理者,声明了一个处理请求的接口,该接口通常仅包含单个方法用于请求处理,但有时还会包含一个设置后继者的方法。
ConcreteHandler是具体处理者,处理它所负责的请求,每个处理者接收到请求后,都必须决定是否进行处理,以及是否向下传递请求。可访问它的后继者,如果可处理该请求就处理,否则就将该请求转发给它的后继者。
处理者通常是独立且不可变的, 需要通过构造函数一次性地获得所有必要地数据。
责任链模式类图表示如下:
伪代码实现
接下来将使用代码介绍下责任链模式的实现。
// 1、Handler是抽象处理者,声明了一个处理请求的接口,另外还包含一个设置后继者的方法
public abstract class Handler {
private Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
protected void doNext() {
if (nextHandler != null) {
nextHandler.handleRequest();
}
}
public abstract void handleRequest();
}
// 2、具体处理者,处理它所负责的请求,接收到请求后,决定是否进行处理,以及是否向下传递请求
public class ConcreteHandlerA extends Handler {
@Override
public void handleRequest() {
System.out.println("I am a concrete handler A instance");
doNext();
}
}
public class ConcreteHandlerB extends Handler {
@Override
public void handleRequest() {
System.out.println("I am a concrete handler B instance");
doNext();
}
}
// 3、客户端
public class ResponsibilityClient {
public void test() {
// (1) 创建处理器实例
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
// (2) 定义先后顺序
handlerA.setNextHandler(handlerB);
// (3) 处理请求
handlerA.handleRequest();
}
}
适用场景
在以下情况下可以考虑使用责任链模式:
(1) 当必须按顺序执行多个处理者时, 可以使用该模式。无论以何种顺序将处理者连接成一条链,所有请求都会严格按照顺序通过链上的处理者。
(2) 当需要使用不同方式处理不同种类请求,而且请求类型和顺序预先未知时,可以使用责任链模式。该模式能将多个处理者连接成一条链。
接收到请求后, 它会 “询问” 每个处理者是否能够对其进行处理。这样所有处理者都有机会来处理请求。
(3) 如果所需处理者及其顺序必须在运行时进行改变, 可以使用责任链模式。如果在处理者类中有对引用成员变量的设定方法, 你将能动态地插入和移除处理者, 或者改变其顺序。
优缺点
责任链模式有以下优点:
(1) 提高了灵活性。请求处理的顺序可以按需控制,提高了系统的灵活性。
(2) 符合开闭原则。可以在不更改现有代码的情况下在程序中新增处理者。
(3) 符合单一职责原则。发起操作和执行操作的类进行解耦。
但是该模式也存在以下缺点:
(1) 性能可能会受到影响。职责链的链路不宜过长,可能会引入性能问题。
(2) 不能保证请求一定被接收。因为没有指定处理者,所以存在请求直到链的末尾都得不到处理的情况。
参考
《设计模式 可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著, 李英军, 马晓星等译
https://refactoringguru.cn/design-patterns/chain-of-responsibility 责任链模式
https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html 责任链模式
https://www.cnblogs.com/adamjwh/p/10932216.html 简说设计模式——职责链模式