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

一站式了解责任链模式


文章目录

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


引言

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

这次我们要讲的是责任链模式,这是在实际的开发中非常常用的软件设计模式,为什么呢?又得讲到那个非常经典的例子了,你是一个程序员,今天临时起意想要暂时远离一下这种枯燥生活,去旅游或者休息,于是你在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.xdnf.cn/news/14739.html

相关文章:

  • c++ 虚继承
  • C# 将 Enum枚举转成List,并显示在下拉列表中
  • 加密货币:比特币
  • Python中布尔值在函数中的巧妙运用
  • 单片机开发日志cv MDK-ARM工具链迁移到MAKE
  • 自动化性能回退机制——蓝绿部署与灰度发布
  • Python 中设置布尔值参数为 True 来启用验证
  • 分布式系统中的 Kafka:流量削峰与异步解耦(二)
  • 「Linux文件及目录管理」硬链接与软连接
  • Spring WebFlux和Spring MVC的对比
  • AR 眼镜之-条形码识别-实现方案
  • Lua 事务双写、RedisGears 异步双写、零停机索引迁移与容量预估
  • PLuTo 编译器示例17-20
  • Unix、Linux、POSIX、Minix 区别与联系
  • 大内存对电脑性能有哪些提升
  • 云计算处理器选哪款?性能与能效的平衡艺术
  • Transformer实战——Hugging Face环境配置与应用详解
  • 深入理解JVM执行引擎
  • C++ inline变量
  • 开源ChatBI :深入解密 Spring AI Alibaba 的中文NL2SQL智能引擎
  • css语法中的选择器与属性详解:嵌套声明、集体声明、全局声明、混合选择器
  • 算法打卡22天
  • 如何在 MX Linux 上安装 Remmina
  • 简单理解HTTP/HTTPS协议
  • PGCE 认证-PostgreSQL 中级专家企业级能力背书,培训直通技术核心
  • 详解鸿蒙Next仓颉开发语言中的全屏模式
  • 从Excel到知识图谱再到数据分析:数据驱动智能体构建指南
  • 短视频批量混剪怎么做?
  • 关系数据库中的事务——SqlServer为例说明
  • 【强化学习】PPO(Proximal Policy Optimization,近端策略优化)算法