含义
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
作用
职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
使用场景
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3、可动态指定一组对象处理请求。
应用实例
背景
入库数据中可能存在特殊数据,入库工具需要具备对特殊数据进行过滤的能力。上线后,如发现有特殊数据需过滤,添加对应的该数据的过滤逻辑即可,方便进行扩展。
分析
使用责任链设计模式,数据沿着过滤链传递,可定义不同的过滤链对象,实现不同的过滤逻辑,对数据进行过滤,后续如果有新的过滤需求,添加一条新的数据过滤链即可,方便扩展。
类图
一期过滤链类图
一期是使用的是传统责任链模型,存在以下问题
- 链的形成是通过在过滤链类中指定后继链来完成,稍有不慎链前后设置错误,就可能形成环结构,造成循环调用。
- 传统责任链模式为链执行逻辑方法中调用下一个链的方法,如果链的长度很大,有因类方法的执行时为出栈和入栈的过程,多层嵌套方法入栈,很可能回造成Java虚拟机栈溢出。
- 一期时链的初始化都是在程序中内置的,不能够根据需求进行动态配置。
二期优化后类图
二期优化点
- 将链放到一个有序的容器中,执行时遍历该容器来执行链逻辑,防止依赖错误造成循环调用。
- 通过遍历容器来执行链,每条链的逻辑方法执行结束再执行下一条链的逻辑,避免了在一条链方法内多层调用子链的方法,可能造成Java虚拟机栈溢出。
- 使用工厂➕反射➕配置,可以通过配置链的类路径和顺序来动态的初始化链结构,使程序的可扩展性更好。
代码样例
数据过滤链基类
非法字符处理链类
字段数验证处理链
过滤链配置信息
读取过滤链配置,并初始化
核心方法有两个一个是初始化方法,读取配置使用反射实例化过滤链对象,放入TreeMap中,保证过滤链处理顺序和配置一致,核心代码如下
还有一个方法为执行过滤链,遍历TreeMap依次执行过滤链
使用过滤链代码片段
优点
- 降低耦合度。它将请求的发送者和接收者解耦。
- 简化了对象。使得对象不需要知道链的结构。
- 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
- 增加新的请求处理类很方便。
缺点
- 不能保证请求一定被接收。
- 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
- 可能不容易观察运行时的特征,有碍于除错。
版权声明:本文为weixin_42588332原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。