Chiriri's blog Chiriri's blog
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)

Iekr

苦逼后端开发
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)
  • JavaSE

  • JavaEE

  • Linux

  • MySQL

  • NoSQL

  • Python

  • Python模块

  • 机器学习

  • 设计模式

    • 设计模式的概念
    • 创建型模式
    • 单例(Singleton)模式
    • 原型(Prototype)模式
    • 工厂(Factory)模式
    • 建造者(Builder)模式
    • 结构型模式(Structural Pattern)
    • 适配器模式(Adapter Pattern)
    • 桥接模式(Bridge Pattern)
    • 装饰器模式(Decorator、Wrapper(包装) Pattern)
    • 代理模式(Proxy Pattern)
    • 外观模式(Facade Pattern)
    • 组合模式(Composite Pattern)
    • 享元模式(Flyweight Pattern)
    • 行为型模式(Behavioral Patterns)
    • 模板方法(Template Method)
    • 策略(Strategy)模式
    • 状态(State)模式
    • 中介者(Mediator)模式
    • 观察者(Observer)模式
    • 备忘录(Memento)模式
    • 解释器(Interpreter)模式
    • 命令(Command)模式
    • 迭代器(Iterator)模式
    • 访问者(Visitor)模式
    • 职责链(Chain of Responsibility)模式
      • 实现一个简单的filter链
      • 应用场景
      • 注意事项和细节
    • 总结
  • 传智健康

  • 畅购商城

  • 博客项目

  • JVM

  • JUC

  • Golang

  • Kubernetes

  • 硅谷课堂

  • C

  • 源码

  • 神领物流

  • RocketMQ

  • 短链平台

  • 后端
  • 设计模式
Iekr
2023-12-10
目录

职责链(Chain of Responsibility)模式

# 职责链(Chain of Responsibility)模式

为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。属于对象行为型模式

  • 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
  • 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
  • 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

image-20231210231052086

public class Teacher {

    private String name;

    public Teacher(String name) {
        this.name = name;
    }

    private Teacher next; // 下一个处理的老师;1、链条的引用点

    public Teacher getNext() {
        return next;
    }

    public void setNext(Teacher next) {
        this.next = next;
    }

    void handleRequest() {
        System.out.println(this + "正在处理....");
        ///2、下一个继续
        if (next != null) {
            next.handleRequest();
        }
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", next=" + next +
                '}';
    }
}
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

测试

public class MainTest {
    public static void main(String[] args) {
        Teacher teacher = new Teacher("王武");
        Teacher teacher1 = new Teacher("张三");
        Teacher teacher2 = new Teacher("李四");

        //3、构建链条
        teacher.setNext(teacher1);
        teacher1.setNext(teacher2);
        teacher.handleRequest();
    }


}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 实现一个简单的 filter 链

对象类,只是传递中的一部分

@Data
public class Request {
    String msg;

    public Request(String msg) {
        this.msg = msg;
    }


}
1
2
3
4
5
6
7
8
9
10
@Data
public class Response {
    String content;

    public Response(String content) {
        this.content = content;
    }
}
1
2
3
4
5
6
7
8

抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。

public interface Filter {
    void doFilter(Request request,Response response,FilterChain chain);
}
1
2
3

具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。

public class CharacterFilter implements Filter {
    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        // 功能
        request.msg += "===";
        System.out.println("CharacterFilter...doFilter之前");
        chain.doFilter(request, response, chain);
        System.out.println("CharacterFilter...doFilter之后");
    }
}
1
2
3
4
5
6
7
8
9
10
public class EncodingFilter implements Filter {
    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        request.msg += "1111";
        System.out.println("EncodingFilter...doFilter之前");
        chain.doFilter(request, response, chain);
        System.out.println("EncodingFilter...doFilter之后");
    }
}
1
2
3
4
5
6
7
8
9
public class HttpFilter implements Filter {
    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        // 第一个filter的功能
        request.msg += ">>>";

        //往下放行
        System.out.println("HttpFilter...doFilter之前");
        chain.doFilter(request, response, chain);
        System.out.println("HttpFilter...doFilter之后");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

public class My {
    void hello() {
        System.out.println("调用my.hello()");
    }
}
1
2
3
4
5
public class FilterChain implements Filter {
    // filter的链条
    List<Filter> filters = new ArrayList<>();
    private int cursor = 0;

    // 最终要执行的目标方法
    @Getter
    My target;

    public void setTarget(My target) {
        this.target = target;
    }

    void addFilter(Filter filter) {
        filters.add(filter);
    }

    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        //执行filter 一直往下
        if (cursor < filters.size()) {
            Filter filter = filters.get(cursor);
            cursor++;
            filter.doFilter(request, response, chain);
        } else {
            // filter完了 执行目标方法
            target.hello();
        }

    }

}
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

测试

public class MainTest {
    public static void main(String[] args) {
        FilterChain chain = new FilterChain();

        HttpFilter httpFilter = new HttpFilter();
        chain.addFilter(httpFilter);
        CharacterFilter characterFilter = new CharacterFilter();
        chain.addFilter(characterFilter);
        EncodingFilter encodingFilter = new EncodingFilter();
        chain.addFilter(encodingFilter);

        chain.setTarget(new My());
        //filter如何链式执行
        chain.doFilter(new Request("hello world"), new Response("test"), chain);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 应用场景

什么场景用到?

  • Tomcat 的 Pipeline、Valve
  • Filter 链
  • Aop 责任链

SpringMVC-HandlerExecutionChain 类就使用到职责链模式

image-20231210235504630

  • springmvc 请求的流程图中,执行了 拦截器相关方法 interceptor.preHandler 等等
  • 在处理 SpringMvc 请求时,使用到职责链模式还使用到适配器模式
  • HandlerExecutionChain 主要负责的是请求拦截器的执行和请求处理,但是他本身不处理请求,只是将请求分配给链上注册处理器执行,这是职责链实现方式,减少职责链本身与处理逻辑之间的耦合,规范了处理流程
  • HandlerExecutionChain 维护了 HandlerInterceptor 的集合, 可以向其中注册相应的拦截器.

# 注意事项和细节

  1. 将请求和处理分开,实现解耦,提高系统的灵活性
  2. 简化了对象,使对象不需要知道链的结构
  3. 性能会受到影响,特别是在 链比较长的时候,因此需控制链中最大节点数量,一般通过在 Handler 中设置一个最大节点数量,在 setNext () 方法中判断是否已经超过阀值,超过则不允许该链建立,避免出现超长链无意识地破坏系统性能
  4. 调试不方便。采用了类似递归的方式,调试时逻辑可能比较复杂
  5. 最佳应用场景:有多个对象可以处理同一个请求时,比如:多级请求、请假 / 加薪等审批流程、Java Web 中 Tomcat 对 Encoding 的处理、拦截器
编辑 (opens new window)
上次更新: 2023/12/13, 06:06:02
访问者(Visitor)模式
总结

← 访问者(Visitor)模式 总结→

最近更新
01
k8s
06-06
02
进程与线程
03-04
03
计算机操作系统概述
02-26
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Iekr | Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式