行为型模式
- 模板方法模式(Template Method Pattern)
- 命令模式(Command Pattern)
- 迭代器模式(Iterator Pattern)
- 观察者模式(Observer Pattern)
- 中介者模式(Mediator Pattern)
- 备忘录模式(Memento Pattern)
- 解释器模式(Interpreter Pattern)
- 状态模式(State Pattern)
- 策略模式(Strategy Pattern)
- 职责链模式(Chain of Responsibility Pattern)
- 访问者模式(Visitor Pattern)
职责链模式(Chain of Responsibility Pattern)
职责链模式(Chain of Responsibility Pattern)是一种行为型设计模式,旨在将请求的发送者和接收者解耦,通过多个处理对象串成一条链,每个对象都有机会处理这个请求,直到有一个对象处理它为止。也就是说,请求沿着链中的每个对象传递,直到有一个对象处理了它,或者链的末尾都没有对象处理这个请求。
主要思想
- 将多个处理对象连接成一个链条:每个对象都持有对下一个处理对象的引用,并且每个对象可以决定是否处理请求,或者将请求传递给链上的下一个对象。
- 解耦请求发送者和接收者:请求发送者不需要知道哪个对象最终会处理它,只需要传递给链条中的第一个对象,由链条内部决定如何分配请求。
1. 结构组成
职责链模式通常包含以下几个角色:
- Handler(处理者):抽象处理者角色,定义处理请求的方法。如果能处理请求,则进行处理;否则,将请求传递给下一个处理者。
- ConcreteHandler(具体处理者):每个具体处理者实现处理请求的逻辑,并决定是否将请求传递给下一个处理者。
- Client(客户端):发送请求的角色,客户端将请求提交给职责链的第一个处理者。
2. 工作原理
职责链模式的工作原理通常如下:
- 客户端将请求提交给链上的第一个处理者。
- 第一个处理者判断自己是否能够处理该请求。如果能处理,就执行处理逻辑;如果不能处理,就将请求传递给链上的下一个处理者。
- 请求继续在链上被传递,直到有一个处理者处理该请求,或者链上的所有处理者都不能处理该请求。
下面是职责链模式的 Java 实现示例:
1. 定义 Handler(抽象处理者)
首先定义一个抽象的 Handler
类,这个类包含一个 setNext
方法用于设置下一个处理者,以及一个 handleRequest
方法用于处理请求。
abstract class Handler {protected Handler nextHandler; // 下一个处理者// 设置下一个处理者public void setNext(Handler nextHandler) {this.nextHandler = nextHandler;}// 处理请求的方法,子类需要实现具体的处理逻辑public abstract void handleRequest(String request);
}
2. 定义具体的处理者(ConcreteHandler)
接下来,我们创建具体的处理者类,每个处理者会根据请求的类型来决定是否处理该请求。如果不能处理,则传递给下一个处理者。
class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(String request) {if ("A".equals(request)) {System.out.println("ConcreteHandlerA 处理请求 A");} else if (nextHandler != null) {System.out.println("ConcreteHandlerA 无法处理请求 A,传递给下一个处理者");nextHandler.handleRequest(request);}}
}class ConcreteHandlerB extends Handler {@Overridepublic void handleRequest(String request) {if ("B".equals(request)) {System.out.println("ConcreteHandlerB 处理请求 B");} else if (nextHandler != null) {System.out.println("ConcreteHandlerB 无法处理请求 B,传递给下一个处理者");nextHandler.handleRequest(request);}}
}class ConcreteHandlerC extends Handler {@Overridepublic void handleRequest(String request) {if ("C".equals(request)) {System.out.println("ConcreteHandlerC 处理请求 C");} else if (nextHandler != null) {System.out.println("ConcreteHandlerC 无法处理请求 C,传递给下一个处理者");nextHandler.handleRequest(request);}}
}
3. 客户端代码(Client)
客户端代码负责构建处理链,并发送请求。
public class Client {public static void main(String[] args) {// 创建具体处理者Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();Handler handlerC = new ConcreteHandlerC();// 设置职责链,A -> B -> ChandlerA.setNext(handlerB);handlerB.setNext(handlerC);// 客户端请求System.out.println("客户端请求 A:");handlerA.handleRequest("A");System.out.println("\n客户端请求 B:");handlerA.handleRequest("B");System.out.println("\n客户端请求 C:");handlerA.handleRequest("C");System.out.println("\n客户端请求 D:");handlerA.handleRequest("D");}
}
6. 优缺点
优点:
- 解耦请求发送者和接收者:客户端无需了解请求将由哪个具体处理者处理,只需要将请求发送到链上的第一个处理者,解耦了客户端与具体处理者之间的关系。
- 责任分担:每个处理者只需要关心自己能处理的部分,不需要关心其他部分的实现。
- 灵活的动态处理:可以动态地修改链的结构,例如在链中添加或移除处理者,或者调整处理者的顺序。
缺点:
- 链的处理效率低:如果请求链很长,每个请求可能需要经过多个处理者才能被处理,影响性能。
- 调试困难:由于请求在多个处理者之间传递,追踪请求的处理过程可能较为困难。
- 处理顺序不容易管理:如果链上的处理者比较多,可能会出现某些处理者优先级问题,导致业务逻辑变得复杂。
7. 应用场景
职责链模式特别适合以下场景:
- 请求的处理需要多个对象参与,而且这些对象的处理逻辑可能会变化或不固定。例如,权限校验、日志处理、审批流程等。
- 多个对象可以处理同一个请求,并且具体处理的顺序不确定时,使用职责链可以灵活处理。
- 需要避免请求和具体处理者之间的耦合,可以将不同的处理者通过职责链串联起来,降低系统耦合度。
典型应用:
- UI事件处理:例如浏览器中的事件监听机制,多个事件监听器(如按钮点击、文本框输入等)通过事件链处理同一事件。
- 审批流程:例如在公司审批流程中,员工提交的申请需要不同级别的管理人员进行审批,可以使用职责链模式来分级处理。
- 日志处理:在多级日志系统中,可以根据日志级别逐步将日志传递给相应的处理器(如文件日志、数据库日志、控制台输出等)。
8. 总结
职责链模式通过将请求和处理逻辑分离,灵活地将多个处理对象连接成一个链。它的最大优势在于解耦了请求发送者和接收者,使得请求可以被链上的多个处理者灵活地处理。通过灵活配置链的结构,可以提高系统的扩展性和灵活性,但也可能增加调试和性能优化的难度。在实际开发中,职责链模式可以应用于事件处理、权限验证、审批流程等多个场景。
文中的示例代码在我的码云:https://gitee.com/ming-super/design-model.git