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

一站式了解责任链模式


文章目录

  • 引言
  • 责任链模式的定义😯
    • 责任链模式的核心思想
    • 使用场景
    • 结构组成
  • 责任链模式的具体使用😎
    • 责任链装载接口
    • 责任链接口
    • 责任链抽象类
    • 责任链具体节点(黑名单节点示例)
    • 默认节点
    • 责任链工厂
  • 测试使用😈
  • 总结❤️


引言

这是设计模式专栏的第二篇文章,在这个专栏里面会讲到我们在开发中经常使用的设计模式,我会用心将它们解析,然后讲给你们听,如果感兴趣可以持续关注这个专栏❤️

这次我们要讲的是责任链模式,这是在实际的开发中非常常用的软件设计模式,为什么呢?又得讲到那个非常经典的例子了,你是一个程序员,今天临时起意想要暂时远离一下这种枯燥生活,去旅游或者休息,于是你在OA系统提起了七天的假期申请,需要流程审批。首先你的组长会看到这个审批,但是他没有权限审批七天的假期,又到你的Leader审批,但是他也同样没有这么大的权限,这个审批一直流转,终于流到了有能力审批七天假期的部门大佬…

这种像一个链子一样的,允许多个对象处理请求,请求会沿着建造好的链子前进,一直达到有能力处理的节点,这种就是责任链模式。

责任链模式的定义😯

上面说了这么多,那么责任链模式定义到底是什么呢?

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象有机会处理请求,从而避免请求的发送者和接收者之间的耦合。请求沿着一条链传递,直到有一个对象处理它为止。

责任链模式的核心思想

  • 将多个处理器连接成一条链
  • 请求从链的一端发起,沿着链传递,每个节点都有机会处理请求或将其传递给下一个节点。
  • 如果当前节点不能处理该请求,则将请求转发给下一个节点。

使用场景

  1. 请求的处理有多个步骤或条件,例如审批流程、权限控制等。
  2. 请求的处理者不确定是谁,希望动态指定。
  3. 解耦请求发送者和处理者,使系统更灵活、可扩展。

结构组成

  • Handler(抽象处理者) :定义处理请求的接口,通常包含一个指向下一个处理者的引用。
  • ConcreteHandler(具体处理者) :实现处理逻辑。可以决定是否处理请求或将请求传给下一个处理者。
  • Client(客户端) :创建处理链并提交请求。

责任链模式的具体使用😎

上面的定义太枯燥了,直接来看怎么使用责任链模式吧,这里笔者选取了自己最熟悉也是觉得最好用的实现方式来给大家看看,如果有佬觉得还有更好的实现方式欢迎在评论区留言或者私信交流🤓

ps:笔者只展示最主要的部分,请大家集中注意力关注主要部分

责任链装载接口

这里是责任链的装载接口,appendNext负责添加下一个责任链节点,next()负责返回责任链中的下一个节点

public interface ILogicChainArmory {ILogicChain appendNext(ILogicChain next);ILogicChain next();
}

责任链接口

这个责任链接口,就是对应的节点类型,logic方法就是每个具体节点都要实现的逻辑

public interface ILogicChain extends ILogicChainArmory{DefaultChainFactory.StrategyAwardVO logic(String userId, Long strategyId);}

责任链抽象类

由于ILogicChain extends ILogicChainArmory,实现子接口的类也必须提供这些方法的具体实现。

但是因为AbstractLogicChain是抽象类,所以实现任意一部分就行了(甚至可以不实现),这里我们实现责任链的装载方法,让具体责任链实现节点类只需要负责实现具体逻辑logic就行,不需要关注其他多余实现(设计模式的各司其职)

public abstract class AbstractLogicChain implements ILogicChain{private ILogicChain next;@Overridepublic ILogicChain appendNext(ILogicChain next) {this.next = next;return next;}@Overridepublic ILogicChain next() {return next;}

责任链具体节点(黑名单节点示例)

这里是一个责任链的具体节点,继承了上面的抽象类,实现具体逻辑即可

@Slf4j
@Component("rule_blacklist")
public class BackListLogicChain extends AbstractLogicChain {@Resourceprivate IStrategyRepository repository;@Overridepublic DefaultChainFactory.StrategyAwardVO logic(String userId, Long strategyId) {//获得对应策略,黑名单的用户配置和奖品配置String ruleValue = repository.queryStrategyRuleValue(strategyId, ruleModel());String[] splitRuleValue = ruleValue.split(Constants.COLON);Integer awardId = Integer.parseInt(splitRuleValue[0]);String[] userBlackIds = splitRuleValue[1].split(Constants.SPLIT);// 黑名单判断for (String userBlackId : userBlackIds) {if (userId.equals(userBlackId)) {return DefaultChainFactory.StrategyAwardVO.builder().awardId(awardId).logicModel(ruleModel()).build();}}// 过滤其他责任链return next().logic(userId, strategyId);}
}

默认节点

这是一个默认的责任链节点,代表请求最终一定可以处理

@Slf4j
@Component("default")
public class DefaultLogicChain extends AbstractLogicChain {@Resourceprotected IStrategyDispatch strategyDispatch;@Overridepublic DefaultChainFactory.StrategyAwardVO logic(String userId, Long strategyId) {Integer awardId = strategyDispatch.getRandomAwardId(strategyId);return DefaultChainFactory.StrategyAwardVO.builder().awardId(awardId).logicModel(ruleModel()).build();}
}

责任链工厂

这里是责任链工厂,负责装载责任链。通过Spring的依赖注入,我们可以很方便的得到所有实现了ILogicChain的具体实现类,通过一个map类型来承载(只有打上注解@Component的具体节点实现类才可以被Spring的bean容器管理)

@Service
public class DefaultChainFactory {private final Map<String, ILogicChain> logicChainGroup;private final IStrategyRepository repository;public DefaultChainFactory(Map<String, ILogicChain> logicChainGroup, IStrategyRepository repository) {this.logicChainGroup = logicChainGroup;this.repository = repository;}public ILogicChain openLogicChain(Long strategyId) {StrategyEntity strategy = repository.queryStrategyEntityByStrategyId(strategyId);//获得该策略对应的ruleModelsString[] ruleModels = strategy.ruleModels();// 如果未配置策略规则,则只装填一个默认责任链if (null == ruleModels || 0 == ruleModels.length) return logicChainGroup.get("default");// 按照配置顺序装填用户配置的责任链ILogicChain logicChain = logicChainGroup.get(ruleModels[0]);ILogicChain current = logicChain;for (int i = 1; i < ruleModels.length; i++) {ILogicChain nextChain = logicChainGroup.get(ruleModels[i]);current = current.appendNext(nextChain);}// 责任链的最后装填默认责任链current.appendNext(logicChainGroup.get("default"));return logicChain;}}

测试使用😈

通过openLogicChain我们就可以获得责任链的头节点,请求放进去就可以在里面流转,最终一定会被处理

@Test
public void test_LogicChain_rule_blacklist() {ILogicChain logicChain = defaultChainFactory.openLogicChain(100001L);DefaultChainFactory.StrategyAwardVO awardId = logicChain.logic("user001", 100001L);log.info("测试结果:{}", awardId);
}

总结❤️

这就是责任链模式的解析,我们下次再见。

如果你看了这篇文章有收获可以点赞+关注+收藏🤩,这是对笔者更新的最大鼓励!如果你有更多方案或者文章中有错漏之处,请在评论区提出帮助笔者勘误,祝你拿到更好的offer!

http://www.lryc.cn/news/573192.html

相关文章:

  • Taro 跨端应用性能优化全攻略:从原理到实践
  • 抖音的视频怎么下载下来——下载狗解析工具
  • 【StarRocks系列】StarRocks vs Mysql
  • 【StarRocks系列】join查询优化
  • 【软考高级系统架构论文】论软件设计方法及其应用
  • 【软考高级系统架构论文】论NoSQL数据库技术及其应用
  • springboot通过独立事务管理器实现资源隔离与精准控制​
  • 基于Python、tkinter、sqlite3 和matplotlib的校园书店管理系统
  • AI大模型学习之基础数学:微积分在AI大模型中的核心-梯度与优化(梯度下降)详解
  • ZooKeeper 3.9.2 集群安装指南
  • 【LeetCode#第228题】汇总区间(简单题)
  • ad24智能pdf输出的装配图没有四个边角那里的圆孔
  • 1、自然语言处理任务全流程
  • `customRef` 在实战中的使用:防抖、计算属性缓存和异步数据获取
  • Duende Identity Server学习之一:认证服务器及一个Oidc/OAuth认证、用于Machine 2 Machine的客户端
  • 【C/C++】Gtest + GMock 简单使用示例
  • Android Studio 打 APK 包报错 Invalid keystore format 的解决方法
  • python web开发-Flask数据库集成
  • Solidity内部合约创建全解析:解锁Web3开发新姿势
  • 分布式锁 不同的拒绝策略 应用场景 业务上的思考
  • Docker简单介绍与使用以及下载对应镜像(项目前置)
  • AWS RDS/Aurora 开启 Database Insights 高级模式全攻略
  • C++11 std::thread 多线程编程详解
  • Python从入门到实战学习笔记(二)
  • 如何用 eBPF 实现 Kubernetes 网络可观测性?实战指南
  • PowerBI HtmlContent生成表格
  • Spring MVC异常处理机制
  • Java求职者面试指南:微服务技术与源码原理深度解析
  • 数据分析核心指标体系:从求和、计数到比较的全维度计算方法
  • 全面深入理解加法器架构:从全加器到并行前缀优化