设计模式之责任链模式【Java实现】

责任链(Chain of Resposibility) 模式

概念

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

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

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

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

代码

需求1:a1 -> a2 -> a3

实现先a1处理完交给a2,a2处理完再交给a3的逻辑,即: a1 -> a2 -> a3

java 复制代码
public class Teacher {

    private String name;

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

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

    public Teacher getNext() {
        return next;
    }

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

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

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                '}';
    }
}
java 复制代码
public class MainTest {
    public static void main(String[] args) {
        Teacher a1 = new Teacher("a1");
        Teacher a2 = new Teacher("a2");
        Teacher a3 = new Teacher("a3");

        // 3、构造链条
        // a1->a2->a2
        a1.setNext(a2);
        a2.setNext(a3);

        a1.handlerRequest();

    }
}

测试结果:

java 复制代码
Teacher{name='a1'}正在处理。。。。。。。。
Teacher{name='a2'}正在处理。。。。。。。。
Teacher{name='a3'}正在处理。。。。。。。。

需求2:1->2->3->本人->3->2->1

这个也就是我们学习过的Filter了

代码实现:

① Filter 接口

java 复制代码
public interface Filter {
    void doFilter(Request request,Response response,FilterChain chain);
}
java 复制代码
@Data
public class Request {
    // 请求内容
    String msg;

    public Request(String msg) {
        this.msg = msg;
    }
}
java 复制代码
@Data
public class Response {

    // 响应内容
    private String content;

    public Response(String content) {
        this.content = content;
    }
}

② Filter 的三个实现类

java 复制代码
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之后");
    }
}
java 复制代码
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之后");
    }
}
java 复制代码
public class EncodingFilter implements Filter {
    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        // 功能
        request.msg += "oooo";

        System.out.println("EncodingFilter ... doFilter之前");
        // 放行
        chain.doFilter(request, response, chain);
        System.out.println("EncodingFilter ... doFilter之后");
    }
}

③ 我们的目标方法

java 复制代码
public class My {
    void hello() {

        System.out.println("调用my.hello()方法");
    }
}

```![在这里插入图片描述](https://img-blog.csdnimg.cn/7b173906028e45c7926d7b944096d929.png)


④ 维护链条

```java
/**
 * 靠他维护链条
 * handlerExecutionChain
 *
 * @author zhuicat
 * @since 2023/8/13 8:19
 */
public class FilterChain implements Filter {

    // 游标:记录当前执行的步骤
    int cursor;

    // Filter 的链
    List<Filter> filterChain = new ArrayList<>();

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

    // 添加 filter 方法
    void addFilter(Filter filter) {
        filterChain.add(filter);
    }

    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        // 执行第一个 filter ,一次往下

        // 游标小于总数量filter一直往下获取执行
        if (cursor < filterChain.size()) {
            Filter filter = filterChain.get(cursor);
            cursor++;
            // 执行 filter
            filter.doFilter(request, response, chain);
        } else {
            // filter执行完了,需要执行目标方法了
            target.hello();
        }
    }

    public My getTarget() {
        return target;
    }

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

⑤ 主方法

java 复制代码
public class MainTest {
    public static void main(String[] args) {
        FilterChain chain = new FilterChain();

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

        chain.setTarget(new My());


        // filter 如何链式执行
        chain.doFilter(new Request("hello,world"), new Response("dddddddddddddddddd"), chain);
    }
}

⑥ 执行结果

java 复制代码
HttpFilter ... doFilter之前
CharacterFilter ... doFilter之前
EncodingFilter ... doFilter之前
调用my.hello()方法
EncodingFilter ... doFilter之后
CharacterFilter ... doFilter之后
HttpFilter ... doFilter之后

完成上述需求

相关推荐
代码山河12 分钟前
基本类型转换:自动类型转换与强制类型转换
java·学习·架构·教程·面向对象·项目
Escalating_xu1 小时前
【Linux 网络编程】五种 I/O 模型与非阻塞 I/O:从“等数据”到正确处理 EAGAIN
java·linux·网络
程序猿乐锅2 小时前
万字详解Single-flight(单飞模式)
java·开发语言·分布式·后端·学习·single-flight
Java后端的Ai之路2 小时前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli
AntsData3 小时前
用 12K+ 条亚马逊评论信号,定位机械键盘下一版该改什么
java·大数据·计算机外设
code2cat3 小时前
【随笔】连续批处理:长短请求怎样在迭代之间补位
java·人工智能·后端·大语言模型·vllm
最强小杰3 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai
Flynn Liang3 小时前
Spring AI 2.0 深度解析:ChatClient、Advisor 链与 MCP——Java 工程师的 AI 落地最优解
java·人工智能·spring·大模型·架构设计·spring ai
灿飞3 小时前
Kotlin与Java虚拟机六:基础与类型系统:一切皆对象,但对象有代价
java·kotlin
计算机毕设定制辅导-无忧学长3 小时前
《基于微信小程序健康习惯激励系统设计与实现》
java·spring boot·mysql·微信小程序·uniapp·健康习惯激励系统