学习记录-责任链模式验证参数
学习记录-责任链模式验证参数
1.什么是责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许将请求沿着一个处理链传递,直到链中的某个对象处理它。这样,发送者无需知道哪个对象将处理请求,所有的处理对象都可以尝试处理请求或将请求传递给链上的下一个对象。
2.使用责任链模式的好处
职责单一: 责任链模式可以将每个验证逻辑封装到一个独立的处理器中,每个处理器负责单一的验证职责,符合单一职责原则。
可扩展性: 增加新的验证逻辑时,只需添加新的处理器,而不需要修改现有的代码。
清晰的流程: 将所有验证逻辑组织在一起,使得代码结构更加清晰,易于理解。
3.实现
3.1定义责任链抽象接口
public interface AbstractChainHandler<T> extends Ordered {
/**
* 执行责任链逻辑
*
* @param requestParam 责任链执行入参
*/
void handler(T requestParam);
/**
* @return 责任链组件标识
*/
String mark();
}
3.2创建责任链模式上下文容器
@Component
public final class ChainContext<T> implements ApplicationContextAware, CommandLineRunner {
/**
* 应用上下文,我们这里通过 Spring IOC 获取 Bean 实例
*/
private ApplicationContext applicationContext;
/**
* 保存商家后管责任链实现类
* <p>
* Key:{@link MerchantAdminAbstractChainHandler#mark()}
* Val:{@link MerchantAdminAbstractChainHandler} 一组责任链实现 Spring Bean 集合
* <p>
* 比如有一个优惠券模板创建责任链,实例如下:
* Key:MERCHANT_ADMIN_CREATE_COUPON_TEMPLATE_KEY
* Val:
* - 验证优惠券信息基本参数是否必填 —— 执行器 {@link CouponTemplateCreateParamNotNullChainFilter}
* - 验证优惠券信息基本参数是否按照格式传递 —— 执行器 {@link CouponTemplateCreateParamBaseVerifyChainFilter}
* - 验证优惠券信息基本参数是否正确,比如商品数据是否存在等 —— 执行器 {@link CouponTemplateCreateParamVerifyChainFilter}
* - ......
*/
private final Map<String, List<AbstractChainHandler>> abstractChainHandlerContainer = new HashMap<>();
/**
* 责任链组件执行
*
* @param mark 责任链组件标识
* @param requestParam 请求参数
*/
public void handler(String mark, T requestParam) {
// 根据 mark 标识从责任链容器中获取一组责任链实现 Bean 集合
List<AbstractChainHandler> abstractChainHandlers = abstractChainHandlerContainer.get(mark);
if (CollectionUtils.isEmpty(abstractChainHandlers)) {
throw new RuntimeException(String.format("[%s] Chain of Responsibility ID is undefined.", mark));
}
abstractChainHandlers.forEach(each -> each.handler(requestParam));
}
@Override
public void run(String... args) throws Exception {
// 从 Spring IOC 容器中获取指定接口 Spring Bean 集合
Map<String, AbstractChainHandler> chainFilterMap = applicationContext.getBeansOfType(AbstractChainHandler.class);
chainFilterMap.forEach((beanName, bean) -> {
// 判断 Mark 是否已经存在抽象责任链容器中,如果已经存在直接向集合新增;如果不存在,创建 Mark 和对应的集合
List<AbstractChainHandler> abstractChainHandlers = abstractChainHandlerContainer.getOrDefault(bean.mark(), new ArrayList<>());
abstractChainHandlers.add(bean);
abstractChainHandlerContainer.put(bean.mark(), abstractChainHandlers);
});
abstractChainHandlerContainer.forEach((mark, unsortedChainHandlers) -> {
// 对每个 Mark 对应的责任链实现类集合进行排序,优先级小的在前
unsortedChainHandlers.sort(Comparator.comparing(Ordered::getOrder));
});
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
3.3使用方式
@Service
@RequiredArgsConstructor
public class ServiceImpl extends ServiceImpl<Mapper, DO> implements Service {
private final ChainContext ChainContext;
@Override
public void createCouponTemplate(ReqDTO requestParam) {
// 通过责任链验证请求参数是否正确
ChainContext.handler(ChainBizMarkEnum.XXXXX.name(), requestParam);
// xxxxxx
}
}