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

如何实现并运用责任链模式

(一) 设计思路

责任链模式是一种行为型设计模式,它允许我们将请求的发送者和接收者解耦,让多个对象都有机会处理这个请求。

【场景】参与抽奖活动送礼品,在参与活动之前需要校验活动的状态(开启、关闭)、活动的库存

  • 接口定义:定义责任链的基础接口
    • IActionChainArmory
      • next 方法:获得下一个处理器
      • appendNext 方法:添加下一个处理器
  • 抽象基类:实现责任链的通用逻辑
    • IActionChain 继承 IActionChainArmory
      • action 方法:定义具体的业务处理方法
  • 具体实现:实现具体的规则处理
    • ActivityBaseActionChain 继承 AbstractActionChain
      • action 方法:真正实现处理方法,调用 next().action 进行传递
  • 工厂管理:管理责任链的创建和组装
    • DefaultActivityChainFactory
      • 创建责任链:通过构造函数自动装配所有IActionChain实现类,并建立链式关系。
      • 组装节点顺序:硬编码指定责任链处理器的执行顺序(如先校验活动状态,再校验库存)。
      • 对外暴露入口:通过openActionChain()方法返回组装完成的责任链,供业务方调用。

(二)核心组件

1. 接口定义

/*** 责任链基础接口* 定义责任链的基本操作:获取下一个处理器、设置下一个处理器*/
public interface IActionChainArmory {IActionChain next();IActionChain appendNext(IActionChain next);
}/*** 责任链业务接口* 定义具体的业务处理方法*/
public interface IActionChain extends IActionChainArmory {boolean action(ActivitySkuEntity activitySkuEntity, ActivityEntity activityEntity, ActivityCountEntity activityCountEntity);
}

2. 抽象基类

/*** 责任链抽象基类* 实现责任链的基本结构,持有下一个处理器的引用*/
public abstract class AbstractActionChain implements IActionChain {private IActionChain next;  // 下一个处理器@Overridepublic IActionChain next() {return next;}@Overridepublic IActionChain appendNext(IActionChain next) {this.next = next;return next;}
}

3. 具体实现类

/*** 基础活动规则链* 处理活动的基础校验,如时间、状态等*/
@Component("activity_base_action")
public class ActivityBaseActionChain extends AbstractActionChain {@Overridepublic boolean action(ActivitySkuEntity activitySkuEntity, ActivityEntity activityEntity, ActivityCountEntity activityCountEntity) {log.info("活动责任链-基础信息【有效期、状态】校验开始。");// 1. 校验活动时间if (!checkActivityTime(activityEntity)) {return false;}// 2. 校验活动状态if (!checkActivityState(activityEntity)) {return false;}// 3. 继续执行下一个规则return next().action(activitySkuEntity, activityEntity, activityCountEntity);}
}/*** 库存规则链* 处理活动的库存校验和扣减*/
@Component("activity_sku_stock_action")
public class ActivitySkuStockActionChain extends AbstractActionChain {@Overridepublic boolean action(ActivitySkuEntity activitySkuEntity, ActivityEntity activityEntity, ActivityCountEntity activityCountEntity) {log.info("活动责任链-商品库存处理【校验&扣减】开始。");// 1. 校验库存if (!checkStock(activitySkuEntity)) {return false;}// 2. 扣减库存if (!deductStock(activitySkuEntity)) {return false;}return true;}
}

4. 责任链工厂

静态硬编码方式:

/*** 责任链工厂* 负责创建和组装责任链*/
@Service
public class DefaultActivityChainFactory {private final IActionChain actionChain;/*** 构造函数注入* Spring会自动注入所有IActionChain实现类到map中*/public DefaultActivityChainFactory(Map<String, IActionChain> actionChainGroup) {// 获取基础规则链actionChain = actionChainGroup.get(ActionModel.activity_base_action.code);// 组装责任链actionChain.appendNext(actionChainGroup.get(ActionModel.activity_sku_stock_action.getCode()));}/*** 获取责任链*/public IActionChain openActionChain() {return this.actionChain;}/*** 规则模型枚举* 定义所有规则类型*/@Getter@AllArgsConstructorpublic enum ActionModel {activity_base_action("activity_base_action", "活动的库存、时间校验"),activity_sku_stock_action("activity_sku_stock_action", "活动sku库存");private final String code;private final String info;}
}

动态从数据库中获取配置:

@Service
public class DefaultChainFactory {private final Map<String, ILogicChain> logicChainGroup;protected IStrategyRepository repository;public ILogicChain openLogicChain(Long strategyId) {// 1. 获取策略配置StrategyEntity strategy = repository.queryStrategyEntityByStrategyId(strategyId);String[] ruleModels = strategy.ruleModels();// 2. 如果没有配置规则,使用默认责任链if (null == ruleModels || 0 == ruleModels.length) return logicChainGroup.get("default");// 3. 按照配置顺序构建责任链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);}// 4. 添加默认责任链作为最后的处理器current.appendNext(logicChainGroup.get("default"));return logicChain;}
}

(三)使用方式

/*** 活动服务* 使用责任链处理活动规则*/
@Service
public class RaffleActivityService extends AbstractRaffleActivity {private final DefaultActivityChainFactory defaultActivityChainFactory;public RaffleActivityService(IActivityRepository activityRepository, DefaultActivityChainFactory defaultActivityChainFactory) {super(activityRepository);this.defaultActivityChainFactory = defaultActivityChainFactory;}/*** 处理活动*/public ActivityOrderEntity createRaffleActivityOrder(ActivityShopCartEntity activityShopCartEntity) {// 1. 获取活动信息ActivitySkuEntity activitySkuEntity = activityRepository.queryActivitySku(activityShopCartEntity.getSku());ActivityEntity activityEntity = activityRepository.queryRaffleActivityByActivityId(activitySkuEntity.getActivityId());ActivityCountEntity activityCountEntity = activityRepository.queryRaffleActivityCountByActivityCountId(activitySkuEntity.getActivityCountId());// 2. 执行责任链IActionChain actionChain = defaultActivityChainFactory.openActionChain();boolean result = actionChain.action(activitySkuEntity, activityEntity, activityCountEntity);// 3. 处理结果if (!result) {throw new AppException("活动规则校验失败");}// 4. 创建订单return ActivityOrderEntity.builder().activityId(activityEntity.getActivityId()).userId(activityShopCartEntity.getUserId()).sku(activitySkuEntity.getSku()).build();}
}

(四) 性能考虑

  • 单一职责:每个规则只负责一个具体的业务逻辑
  • 开闭原则:新增规则不需要修改现有代码
  • 可配置性:规则参数可通过配置调整
  • 避免过长责任链
  • 统一异常处理
  • 规则执行回滚
  • 日志记录完整
  • 规则版本控制
  • 规则配置管理
  • 规则监控统计
http://www.xdnf.cn/news/5468.html

相关文章:

  • 英语时态--中英文对“时间”的不同理解
  • 抽奖系统-基本-注册
  • Redis从基础到高阶应用:核心命令解析与延迟队列、事务消息实战设计
  • JVM 监控
  • 【Java学习笔记】多态
  • HTML5中的Microdata与历史记录管理详解
  • 安装typescript时,npm install -g typescript报错
  • .Net HttpClient 处理响应数据
  • 每日一题洛谷P8615 [蓝桥杯 2014 国 C] 拼接平方数c++
  • 被一个人影响情绪是爱吗?这 3 个真相越早明白越好
  • AI面经总结-试读
  • 深度解析六大AI爬虫工具:crawl4ai、FireCrawl、Scrapegraph-ai、Jina、SearXNG、Tavily技术对比与实战指南
  • COT思维链:SequentialChain 方法有哪些参数;优化后的提示词
  • ES面试题系列「一」
  • MySQL的索引分类
  • 软件体系结构(Software Architecture)
  • IDEA:如何设置最上面菜单栏一直显示出来
  • 图片转ICO图标工具
  • 一个网球新手的学习心得
  • 单链表设计与实现
  • 锁相放大技术:从噪声中提取微弱信号的利器
  • C PRIMER PLUS——第9节:动态内存分配、存储类别、链接和内存管理
  • 程序中的内存从哪里来?
  • arctan x 导数推理
  • Java 1.8(也称为Java 8)
  • 4.4 os模块
  • MySql事务索引
  • 图灵奖获得者经典论文系列(1969):迈向人工智能的步伐(马文·明斯基)
  • 2023 河南ccpc
  • Python与矢量网络分析仪3671E:通道插损自动化校准(Vscode)