博客
关于我
不得不知的责任链设计模式
阅读量:403 次
发布时间:2019-03-05

本文共 3323 字,大约阅读时间需要 11 分钟。

责任链设计模式:深入理解与实践

1. 责任链设计模式的核心思想

责任链设计模式(Chain of Responsibility Pattern)是一种行为型设计模式,其核心思想是通过定义一个接收者链,解耦请求的发送者和接收者,使得请求的处理过程可以按照一定的顺序传递下去,直到找到能够处理该请求的对象或者链的结束。

这种设计模式的典型应用场景是处理具有递归性或按顺序执行的任务,例如日志记录、过滤器链、事务处理等。在Java开发中,责任链模式广泛应用于诸如MyBatis拦截器、Spring MVC过滤器链等场景。

2. 概念图形化理解

责任链设计模式可以通过类图和序列图来直观理解:

  • 类图:Sender类通过引用Handler接口来处理请求,而不是直接引用具体的接收者类。这种设计实现了对接收者类的松耦合。
  • 序列图:展示了请求在不同接收者之间的传递过程,例如Sender对象调用Receiver1的handleRequest方法,Receiver1将请求传递给Receiver2,依此类推,直到请求被处理或链结束。

3. 具体实现示例

3.1 Demo设计:Logback日志记录

在实际开发中,责任链设计模式可以通过多个日志记录器组成一个链来实现不同的日志级别处理。例如,Logback框架中的Logger接口通过Lambda表达式实现了责任链:

public interface Logger {    enum LogLevel {        INFO, DEBUG, WARNING, ERROR, FUNCTIONAL_MESSAGE, FUNCTIONAL_ERROR;    }    void message(String msg, LogLevel severity);    default Logger appendNext(Logger nextLogger) {        return (msg, severity) -> {            message(msg, severity);            nextLogger.message(msg, severity);        };    }    static Logger logger(LogLevel[] levels, Consumer
writeMessage) { return (msg, severity) -> { if (levels.contains(severity)) { writeMessage.accept(msg); } }; } static Logger consoleLogger(LogLevel... levels) { return logger(levels, msg -> System.err.println("写到终端: " + msg)); } static Logger emailLogger(LogLevel... levels) { return logger(levels, msg -> System.err.println("通过邮件发送: " + msg)); } static Logger fileLogger(LogLevel... levels) { return logger(levels, msg -> System.err.println("写到日志文件中: " + msg)); }}

通过这种方式,可以灵活配置日志记录链,例如:

Logger logger = consoleLogger(LogLevel.all())    .appendNext(emailLogger(LogLevel.FUNCTIONAL_MESSAGE, LogLevel.FUNCTIONAL_ERROR))    .appendNext(fileLogger(LogLevel.WARNING, LogLevel.ERROR));

3.2 案例分析:Filter链中的责任链

在Web开发中,过滤器链(FilterChain)是责任链设计模式的典型应用之一。例如,Tomcat容器中的ApplicationFilterChain通过管理多个过滤器,按照一定顺序执行每个过滤器的doFilter方法。

3.2.1 责任链的执行流程

  • ApplicationFilterChain维护一个过滤器数组filters。
  • 通过pos变量记录当前处理的位置,每次调用下一个过滤器的doFilter方法。
  • 当pos超过数组长度时,责任链结束。

3.2.2 MyBatis拦截器链

MyBatis框架中的拦截器链也是一个典型的责任链应用。通过InterceptorChain类管理多个拦截器,依次对目标进行处理。例如:

public class InterceptorChain {    private final List
interceptors = new ArrayList<>(); public Object pluginAll(Object target) { for (Interceptor interceptor : interceptors) { target = interceptor.plugin(target); } return target; } public void addInterceptor(Interceptor interceptor) { interceptors.add(interceptor); } public List
getInterceptors() { return Collections.unmodifiableList(interceptors); }}

4. 责任链设计模式的优点

  • 松耦合设计:请求的发送者和接收者解耦,降低了耦合度。
  • 灵活扩展:可以通过动态添加接收者来扩展责任链。
  • 责任明确:每个接收者都有明确的处理职责,责任划分清晰。
  • 递归处理:适合处理递归性任务,例如链式操作。
  • 5. 实际开发中的应用建议

  • 任务分解:将复杂任务拆分为多个小任务,各任务独立处理。
  • 接收者设计:设计接收者类,实现具体的处理逻辑。
  • 动态传递:通过链的方式传递请求,灵活控制处理顺序。
  • 链的终止条件:设计链的结束条件,避免无限循环或资源浪费。
  • 6. 常见问题与解决方案

    6.1 如何处理相同类型的拦截器?

    在MyBatis拦截器中,多个拦截器可以通过依次调用plugin方法来处理同一类型的任务。通过InterceptorChain类的pluginAll方法,依次为目标生成代理对象,实现链式处理。

    6.2 如何控制责任链的执行顺序?

    通过责任链的设计模式,可以通过自定义接收者的顺序来控制执行顺序。例如,通过在初始化链时指定接收者的顺序,或者在运行时动态地修改接收者的链。

    7. 总结与思考

    通过对责任链设计模式的学习与实践,我们可以更好地理解其核心思想,并在实际开发中灵活应用。关键在于:

  • 设计一个处理链条的结构。
  • 将具体处理器初始化到链条中,并实现抽象方法的具体处理。
  • 设计处理器之间的引用关系和处理条件判断。
  • 明确链的结束条件。
  • 在实际业务中,如果需要顺序执行多个任务或处理单元,可以考虑使用责任链设计模式。同时,关注框架源码中的链结构(如chain关键字),往往能发现责任链设计模式的身影。

    如果你有关于Lambda函数式编程在责任链中的应用,或者多个拦截器的责任链顺序控制的具体方案,欢迎在评论区分享你的思考与经验。

    转载地址:http://cgqzz.baihongyu.com/

    你可能感兴趣的文章
    NLP采用Bert进行简单文本情感分类
    查看>>
    NLP问答系统:使用 Deepset SQUAD 和 SQuAD v2 度量评估
    查看>>
    NLP项目:维基百科文章爬虫和分类【02】 - 语料库转换管道
    查看>>
    NLP:使用 SciKit Learn 的文本矢量化方法
    查看>>
    nmap 使用方法详细介绍
    查看>>
    Nmap扫描教程之Nmap基础知识
    查看>>
    nmap指纹识别要点以及又快又准之方法
    查看>>
    Nmap渗透测试指南之指纹识别与探测、伺机而动
    查看>>
    Nmap端口扫描工具Windows安装和命令大全(非常详细)零基础入门到精通,收藏这篇就够了
    查看>>
    NMAP网络扫描工具的安装与使用
    查看>>
    NMF(非负矩阵分解)
    查看>>
    nmon_x86_64_centos7工具如何使用
    查看>>
    NN&DL4.1 Deep L-layer neural network简介
    查看>>
    NN&DL4.3 Getting your matrix dimensions right
    查看>>
    NN&DL4.7 Parameters vs Hyperparameters
    查看>>
    NN&DL4.8 What does this have to do with the brain?
    查看>>
    nnU-Net 终极指南
    查看>>
    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    查看>>
    NO 157 去掉禅道访问地址中的zentao
    查看>>
    no available service ‘default‘ found, please make sure registry config corre seata
    查看>>