当前位置: 首页 > news >正文

设计模式 之 责任链模式

一搜网上讲责任链的写法都感觉好复杂?我用简单实现让你秒懂并马上用到项目里

前言

搜了一圈责任链模式的文章,要么搬出 UML 类图画半天,要么搞一堆HandlerHandlerChainAbstractHandler层层嵌套,看得人头大。

今天分享一个我在实际项目中用的责任链实现,总共就 3 个核心文件,代码不超过 80 行,看完直接就能抄到你的项目里。


一、先说场景:什么时候需要责任链?

当你发现代码里有这种结构时:

if(条件A){// 处理逻辑 A}elseif(条件B){// 处理逻辑 B}elseif(条件C){// 处理逻辑 C}else{// 默认处理}

每加一个场景就要改这个if-else,越写越长,越改越乱。

责任链就是把这个 if-else 拆成一个个独立的处理节点,串起来依次执行。


二、核心就 3 个东西

角色作用对应文件
接口定义"干什么"和"下一个是谁"ILogicChain
抽象类帮你管好"下一个"的引用AbstractLogicChain
实现类每个节点的具体逻辑ReBrushChain/ContextCacheChain/DefaultChain

三、代码逐行拆解

1. 接口 — 定义链的契约

publicinterfaceILogicChain{// 核心方法:处理业务逻辑List<ShardingContext>logic(SalesOrderEnumtype,MageFilterfilter,MetaInfometa);// 获取下一个节点ILogicChainnext();// 追加下一个节点(返回被追加的节点,方便链式调用)ILogicChainappendNext(ILogicChainnext);}

关键点appendNext返回的是ILogicChain而不是void,这样工厂里可以current = current.appendNext(next)一路串下去。


2. 抽象类 — 统一管理 next 引用

@Slf4jpublicabstractclassAbstractLogicChainimplementsILogicChain{privateILogicChainnext;@OverridepublicILogicChainnext(){returnnext;}@OverridepublicILogicChainappendNext(ILogicChainnext){this.next=next;returnnext;// 返回下一个,方便链式组装}// 子类可以标识自己的规则名protectedabstractStringrule();}

就这么简单。next 的存取全在抽象类里,子类完全不用关心链的维护。


3. 实现类 — 每个节点只管自己的事

节点 1:反刷链(优先级最高)
@Order(1)publicclassReBrushChainextendsAbstractLogicChain{@OverrideprotectedStringrule(){return"rebrush";}@OverridepublicList<ShardingContext>logic(SalesOrderEnumtype,MageFilterfilter,MetaInfometa){// 命中我的场景 → 我处理,直接返回if(meta.reBrush()){// ... 构建并返回 brushContextListreturnbrushContextList;}// 不命中 → 交给下一个returnnext().logic(type,filter,meta);}}
节点 2:上下文缓存链
@Order(2)publicclassContextCacheChainextendsAbstractLogicChain{@OverrideprotectedStringrule(){return"context_cache";}@OverridepublicList<ShardingContext>logic(SalesOrderEnumtype,MageFilterfilter,MetaInfometa){ObjectcontextCacheValue=filter.getValue(CustomProperties.INTEGRATION_BATCH_SCOPE);// 命中 → 从缓存取 Scope,直接返回if(null!=contextCacheValue){// ... 构建并返回 contextListreturncontextList;}// 不命中 → 交给下一个returnnext().logic(type,filter,meta);}}
节点 3:默认链(兜底)
@Order(3)publicclassDefaultChainextendsAbstractLogicChain{@OverrideprotectedStringrule(){return"default";}@OverridepublicList<ShardingContext>logic(SalesOrderEnumtype,MageFilterfilter,MetaInfometa){// 兜底节点:直接查数据库拿 ScopeList<ProcessDataScope>scopeList=db.get();returnscopeList;}}

注意:DefaultChain 没有调用next(),因为它是最后一个节点。


4. 工厂 — 把链组装起来

publicclassScopeChainFactory{privatestaticfinalMap<String,ILogicChain>CHAIN_GROUP=newHashMap<>();static{CHAIN_GROUP.put("rebrush",newReBrushChain());CHAIN_GROUP.put("context_cache",newContextCacheChain());CHAIN_GROUP.put("default",newDefaultChain());}// 定义执行顺序privatestaticfinalString[]SCOPE_MODELS=newString[]{"rebrush","context_cache"};publicstaticILogicChainopenChain(){// 拿到头节点ILogicChainlogicChain=CHAIN_GROUP.get(SCOPE_MODELS[0]);ILogicChaincurrent=logicChain;// 依次串起来for(inti=1;i<SCOPE_MODELS.length;i++){ILogicChainnextChain=CHAIN_GROUP.get(SCOPE_MODELS[i]);current=current.appendNext(nextChain);}// default 兜底,确保链不会断current.appendNext(CHAIN_GROUP.get("default"));returnlogicChain;}}

四、调用方怎么用?

一行代码:

List<ShardingContext>result=ScopeChainFactory.openChain().logic(salesType,filter,metaInfo);

调用方完全不用关心内部走了哪个节点,链会自己判断。


五、执行流程图

调用入口 ↓ ReBrushChain (Order=1) ├─ 命中反刷场景? → 处理并返回 └─ 没命中 → next() ↓ ContextCacheChain (Order=2) ├─ 有上下文缓存? → 处理并返回 └─ 没有缓存 → next() ↓ DefaultChain (Order=3, 兜底) └─ 查数据库拿 Scope → 处理并返回

六、和网上的写法比,简单在哪?

对比项网上的写法本文写法
类的数量5-8 个(Handler、Chain、Builder、Context…)3 个(接口、抽象类、实现类)
组装方式Builder 嵌套 / Spring 注入 List 再排序静态 Map + 数组定义顺序
传递方式封装一个 Context 对象层层传递方法参数直接传,清晰明了
终止条件各种 boolean 返回值判断命中就 return,没命中就next()

七、要加新节点怎么办?

3 步:

  1. 新建实现类,继承AbstractLogicChain,实现logic()方法
  2. ScopeChainFactoryCHAIN_GROUP里注册
  3. SCOPE_MODELS数组里加上它的位置

完事。不用改任何已有代码,符合开闭原则。


总结

责任链模式的本质就是:把 if-else 变成一串独立节点,每个节点自己决定"我处理"还是"交给下一个"。

不需要复杂的框架,不需要一堆辅助类。一个接口、一个抽象类、几个实现类、一个工厂,就够了。

直接抄到你的项目里,把logic()方法的参数换成你自己的业务参数,马上就能用。

http://www.jsqmd.com/news/874054/

相关文章:

  • Kubernetes自定义资源:扩展Kubernetes API的能力
  • 机器学习篇---图像分割
  • 2026年5月充电桩建站厂家推荐:十大排名重卡快充评测专业价格 - 品牌推荐
  • 【无人机路径规划】实现有效的水陆两栖无人机任务规划和执行(Matlab实现)(含粒子群优化和遗传算法)
  • AI Agent如何重构咨询交付模式:从人工周级报告到秒级洞察,头部咨询公司内部流程解密
  • 智能是使用者的镜像·维度扩展版|权重不是结果,是你看不见的那一堆因素算出来的
  • 【GUI】正交频分复用(OFDM) 峰均功率比(PAPR)降低仿真器:使用选择映射(SLM)和部分传输序列(PTS)研究(Matlab代码实现)
  • 2026年石家庄金属回收TOP5推荐:石家庄废品回收、石家庄高价回收金属、石家庄高价回收铜铁铝电缆废品、设备回收选择指南 - 优质品牌商家
  • AI 开发工具选择指南:Qoder、Qwen 与开发者使用策略
  • ML模型监控工具:监控和维护机器学习模型的性能
  • 还搞不懂集合?一张图带你吃透 ArrayList、HashMap、ConcurrentHashMap 的底层原理(附7张流程图)
  • 工具要工程化。
  • Codeforces Round 1057
  • 深度学习篇---图像分类、目标检测和图像分割任务对比
  • 多云安全态势:管理多个云环境的安全状态
  • 哪家工控一体机厂家专业?2026年5月推荐TOP5对比案例防尘防震评测特点 - 品牌推荐
  • 软考软件设计师 · 考前5天终极精炼
  • 211本科985硕拿下淘天AI二面!全程无代码,这面试题火了!
  • 2026年第二季度,如何甄选一家可靠的山地车制造合作伙伴? - 2026年企业推荐榜
  • Invoke-Obfuscation深度解析:PowerShell混淆技术的实战指南与防御策略
  • 畜牧场景电加热风机技术拆解与选型实操指南:养鸭专用风机/农业机械/农牧机械设备/冷风机/厂房降温风机/商品鸡平养自动料线/选择指南 - 优质品牌商家
  • 前端全流程求职Skill 攻略
  • 数据主权与伦理治理:构建下一代数字文明框架
  • 镜像视界浙江科技有限公司|数字孪生・视频孪生・无感定位・跨镜追踪 技术地位与核心优势
  • 3个PDF编辑痛点,用这个免费工具轻松搞定!PDF补丁丁全面解析
  • 政务管理领域大模型应用场景
  • Lindy自动化不是IT部门的事!CIO亲述:如何用“业务-技术-合规”三权制衡模型锁定首期300万降本收益
  • 2026年5月主流电竞鼠标品牌十大排行榜推荐:专业评测手型适配案例价格 - 品牌推荐
  • AI英语背单词APP 的开发费用
  • 开源AI Agent:OpenCode集成OMO原理及实践