责任链设计模式详解

打印 上一主题 下一主题

主题 1376|帖子 1376|积分 4128

责任链设计模式详解

一、定义

责任链设计模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许多个对象有机会处理请求,从而避免请求的发送者和吸收者之间的耦合。这种模式将这些对象连接成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。 就是说每个结点会处理一件事变,如果结点间出现异常,那么链路就会制止。
二、责任链的主要布局

主要布局
责任链模式的核心布局可以分为以下几个部门:

  • 抽象处理者(Handler)

    • 定义一个处理请求的接口(通常是一个抽象类),包罗一个方法来处理请求,以及一个指向下一个处理者的引用。
    • 提供设置和获取下一个处理者的方法。

  • 具体处理者(ConcreteHandler)

    • 继承或实现抽象处理者接口。
    • 具体处理请求的实现,如果当前处理者不能处理该请求,则将其传递给下一个处理者。

  • 客户端(Client)

    • 创建处理链的实例并将请求传递给链中的第一个处理者。

三、工作原理

当一个请求发送到责任链中的第一个处理者时,它会检查是否能够处理该请求。如果能够处理,处理者就会处理请求;如果不能处理,它就会将请求传递给下一个处理者,直到找到能够处理请求的处理者大概链的末端。
四、优缺点

优点



  • 解耦:请求的发送者和吸收者之间没有直接关系,发送者无需知道具体哪个处理者处理了请求。
  • 机动性:可以通过动态地添加或删除责任链中的处理者来改变处理请求的逻辑。
  • 增强代码的可扩展性:可以在不修改现有代码的情况下增加新的处理者。
缺点



  • 性能标题:如果链条太长,大概会导致性能标题,尤其是在每个处理者只做很少的处理时。
  • 调试复杂性:由于请求在多个处理者之间传递,调试起来大概会比较困难。
五、Spring MVC框架的责任链模式应用

springmvc流程:



  • 用户发起请求,请求先被 Servlet 拦截转发给 Spring MVC 框架
  • Spring MVC 里面的 DispatcherSerlvet 核心控制器,会吸收到请求并转发给HandlerMapping
  • HandlerMapping 负责解析请求,根据请求信息和配置信息找到匹配的 Controller类,不过这里如果有配置拦截器,就会按照顺序执行拦截器里面的 preHandle方法
  • 找到匹配的 Controller 以后,把请求参数传递给 Controller 里面的方法
  • Controller 中的方法执行完以后,会返回一个 ModeAndView,这里面会包括视图名称和须要传递给视图的模子数据
  • 视图解析器根据名称找到视图,然后把数据模子填充到视图里面再渲染成 Html 内容返回给客户端
过滤器链(Filter Chain):



  • 过滤器是基于 Servlet 规范的,它们用于在请求到达目标 Servlet 之前以及响应返回客户端之前执行一些通用的任务。过滤器链是基于 Servlet 容器的,通常用于处理跨请求的通用任务,比如日志记录、安全检查、压缩等。
  • 责任链模式表现在多个过滤器按配置的顺序依次执行,如果某个过滤器决定拦截请求,则可以中止链条的继承传递。
  • 过滤器链的执行流程

    • 客户端发出请求。
    • 请求首先到达过滤器链,按照配置顺序依次执行。
    • 如果某个过滤器决定不放行请求,可以直接返回响应,从而中止后续的处理流程。
    • 如果所有过滤器都放行,则请求继承到达 Spring MVC 的 DispatcherServlet。

拦截器链(Handler Interceptor):



  • 拦截器是 Spring MVC 提供的更加精细的请求处理机制,允许在控制器方法之前和之后举行拦截处理。
  • HandlerInterceptor 接口提供了三个主要方法:preHandle、postHandle 和 afterCompletion,这些方法可以在请求处理的不同阶段被调用。
  • 在 Spring MVC 的配置中,多个拦截器可以被配置成链式调用,它们之间的关系就是一种典型的责任链模式。请求到达 DispatcherServlet 时,首先会通过拦截器链的 preHandle 方法,如果所有的拦截器都返回 true,请求才会继承到达处理器(Handler)。处理完成后,依次调用拦截器的 postHandle 和 afterCompletion 方法。
  • 拦截器链的执行流程
  • 请求到达 DispatcherServlet 后,根据 Handler Mapping 找到对应的 Controller 处理器。
  • 在 Controller 方法执行之前,拦截器链中的 preHandle 方法依次执行。如果所有 preHandle 方法都返回 true,则继承执行 Controller 方法。
  • Controller 方法执行完毕后,拦截器链中的 postHandle 方法按照配置顺序依次执行。
  • 最后,afterCompletion 方法会在请求完成后执行,用于举行一些资源清理或日志记录等操纵。
处理器映射链(Handler Mapping Chain):



  • 在 Spring MVC 中,处理器映射(Handler Mapping)用于将请求 URL 映射到相应的处理器(Controller)。
  • 可以配置多个处理器映射,通过责任链模式来依次检查每一个映射器,直到找到一个合适的处理器。
  • 处理器映射链的执行流程
  • DispatcherServlet 根据配置的多个 Handler Mapping 依次查找合适的 Controller。
  • 当找到一个匹配的 Controller 时,制止继承查找,并调用该 Controller 处理请求。
六、责任链示例

  1. abstract class Handler {
  2.     protected Handler next;
  3.     public void setNext(Handler next) {
  4.         this.next = next;
  5.     }
  6.     public abstract void handleRequest(int request);
  7. }
  8. class ConcreteHandler1 extends Handler {
  9.     @Override
  10.     public void handleRequest(int request) {
  11.         if (request < 10) {
  12.             System.out.println("Handler1处理请求: " + request);
  13.         } else if (next != null) {
  14.             next.handleRequest(request);
  15.         }
  16.     }
  17. }
  18. class ConcreteHandler2 extends Handler {
  19.     @Override
  20.     public void handleRequest(int request) {
  21.         if (request >= 10 && request < 20) {
  22.             System.out.println("Handler2处理请求: " + request);
  23.         } else if (next != null) {
  24.             next.handleRequest(request);
  25.         }
  26.     }
  27. }
  28. class Client {
  29.     public static void main(String[] args) {
  30.         Handler handler1 = new ConcreteHandler1();
  31.         Handler handler2 = new ConcreteHandler2();
  32.         handler1.setNext(handler2);
  33.         int[] requests = {5, 14, 22};
  34.         for (int request : requests) {
  35.             handler1.handleRequest(request);
  36.         }
  37.     }
  38. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

光之使者

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表