(一) 设计思路
责任链模式是一种行为型设计模式,它允许我们将请求的发送者和接收者解耦,让多个对象都有机会处理这个请求。
【场景】参与抽奖活动送礼品,在参与活动之前需要校验活动的状态(开启、关闭)、活动的库存
- 接口定义:定义责任链的基础接口
- IActionChainArmory
- next 方法:获得下一个处理器
- appendNext 方法:添加下一个处理器
- IActionChainArmory
- 抽象基类:实现责任链的通用逻辑
- IActionChain 继承 IActionChainArmory
- action 方法:定义具体的业务处理方法
- IActionChain 继承 IActionChainArmory
- 具体实现:实现具体的规则处理
- ActivityBaseActionChain 继承 AbstractActionChain
- action 方法:真正实现处理方法,调用 next().action 进行传递
- ActivityBaseActionChain 继承 AbstractActionChain
- 工厂管理:管理责任链的创建和组装
- DefaultActivityChainFactory
- 创建责任链:通过构造函数自动装配所有IActionChain实现类,并建立链式关系。
- 组装节点顺序:硬编码指定责任链处理器的执行顺序(如先校验活动状态,再校验库存)。
- 对外暴露入口:通过openActionChain()方法返回组装完成的责任链,供业务方调用。
- DefaultActivityChainFactory
(二)核心组件
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; // 下一个处理器
@Override
public IActionChain next() {
return next;
}
@Override
public IActionChain appendNext(IActionChain next) {
this.next = next;
return next;
}
}
3. 具体实现类
/**
* 基础活动规则链
* 处理活动的基础校验,如时间、状态等
*/
@Component("activity_base_action")
public class ActivityBaseActionChain extends AbstractActionChain {
@Override
public 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 {
@Override
public 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
@AllArgsConstructor
public 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();
}
}
(四) 性能考虑
- 单一职责:每个规则只负责一个具体的业务逻辑
- 开闭原则:新增规则不需要修改现有代码
- 可配置性:规则参数可通过配置调整
- 避免过长责任链
- 统一异常处理
- 规则执行回滚
- 日志记录完整
- 规则版本控制
- 规则配置管理
- 规则监控统计