博客
关于我
不得不知的责任链设计模式
阅读量: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/

    你可能感兴趣的文章
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
    查看>>
    NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
    查看>>
    NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
    查看>>
    NIFI从PostGresql中离线读取数据再导入到MySql中_带有数据分页获取功能_不带分页不能用_NIFI资料太少了---大数据之Nifi工作笔记0039
    查看>>
    NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
    查看>>
    Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
    查看>>
    NIFI大数据进阶_FlowFile拓扑_对FlowFile内容和属性的修改删除添加_介绍和描述_以及实际操作---大数据之Nifi工作笔记0023
    查看>>
    NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
    查看>>
    NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
    查看>>
    NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
    查看>>
    NIFI大数据进阶_外部ZK模式集群1_实际操作搭建NIFI外部ZK模式集群---大数据之Nifi工作笔记0017
    查看>>
    NIFI大数据进阶_离线同步MySql数据到HDFS_01_实际操作---大数据之Nifi工作笔记0029
    查看>>
    NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
    查看>>
    NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
    查看>>
    NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
    查看>>
    NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001---大数据之Nifi工作笔记0068
    查看>>