设计模式之责任链模式【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之后

完成上述需求

相关推荐
Yan.love5 分钟前
开发场景中Java 集合的最佳选择
java·数据结构·链表
椰椰椰耶8 分钟前
【文档搜索引擎】搜索模块的完整实现
java·搜索引擎
大G哥8 分钟前
java提高正则处理效率
java·开发语言
智慧老师39 分钟前
Spring基础分析13-Spring Security框架
java·后端·spring
lxyzcm40 分钟前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
V+zmm101341 小时前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm
Oneforlove_twoforjob2 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
xmh-sxh-13142 小时前
常用的缓存技术都有哪些
java
AiFlutter2 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter
J不A秃V头A3 小时前
IntelliJ IDEA中设置激活的profile
java·intellij-idea