本文以创建商品案例来讲解责任链模式,.假设创建商品逻辑分为: 1. 创建商品 2. 检验商品 3. 保存商品. 第二步中校验商品又分为多种情况,必填字段校验,规格校验,价格校验,库存校验等等.
伪代码如下:
public Result createProcuct(Product param){
//参数校验
Result paramCheck = this.paramCheck(param);
if (!paramCheck.isSuccess()) {
return paramCheck;
}
//价格校验
Result priceCheck = this.priceCheck(param);
if (!priceCheck.isSuccess()) {
return priceCheck;
}
//库存校验
Result stockCheck = this.stockCheck(param);
if (!stockCheck.isSuccess()) {
return stockCheck;
}
//.....
//保存商品
return this.saveProduct(param);
}
以上代码看起来似乎没什么问题,但是随着公司业务需求不断增加,相关校验也会越来越多,新增功能就需要在原来代码上修改,使代码越来越臃肿,可维护性原来越差,校验不可以复用.下面我们使用责任链模式来优化,实现校验可以编排,动态扩展.
UML类图
1. 创建商品参数对象
@Data
@Builder
public class Product {
/**
* 商品SKU(唯一)
*/
private Long skuId;
/**
* 商品名称
*/
private String skuName;
/**
* 商品图片路径
*/
private String imgPath;
/**
* 价格
*/
private BigDecimal price;
/**
* 库存
*/
private Integer stock;
}
2. 抽象处理器
@Component
@Getter
@Setter
public abstract class AbstractCheckHandler {
/**
* 当前处理器持有的下一个处理器
*/
protected AbstractCheckHandler nextHandler;
/**
* 处理器配置
*/
protected ProductCheckHandlerConfig config;
/**
* 处理器执行方法
* @param param
* @return
*/
public abstract Result handler(Product param);
protected Result next(Product param) {
//下一个链路为空,直接返回
if (nextHandler == null) {
return Result.success();
}
return nextHandler.handler(param);
}
}
3. 处理器配置类
@AllArgsConstructor
@Data
public class ProductCheckHandlerConfig {
/**
* 处理器Bean名称
*/
private String handler;
/**
* 下一个处理器
*/
private ProductCheckHandlerConfig next;
/**
* 是否降级
*/
private boolean down;
}
4. 创建抽象类子类,NullCheckHandler控制校验处理器,PriceChekcHandler价格校验处理器,StockCheckHandler库存校验处理器
@Component
public class NullCheckHandler extends AbstractCheckHandler{
@Override
public Result handler(Product param) {
System.out.println("空值校验开始...");
//降级:如果配置了降级,则跳过此处理器执行下一个处理器
if(super.config.isDown()){
System.out.println("空值校验降级通过");
return super.next(param);
}
//校验逻辑
if(param == null){
return Result.failure("商品参数不能为空");
}
if(param.getSkuId() == null){
return Result.failure("商品SKU不能为空");
}
//省略其它校验
System.out.println("空值校验通过");
return super.next(param);
}
}
@Component
public class PriceCheckHandler extends AbstractCheckHandler{
@Override
public Result handler(Product param) {
System.out.println("价格校验开始...");
//降级:如果配置了降级,则跳过此处理器执行下一个处理器
if(super.config.isDown()){
System.out.println("价格校验降级通过");
return super.next(param);
}
//非法价格校验
if (param.getPrice().compareTo(BigDecimal.ZERO) <=0) {
return Result.failure("价格非法");
}
//其它校验逻辑..
//执行下一个处理器
System.out.println("价格校验通过");
return super.next(param);
}
}
@Component
public class StockCheckHandler extends AbstractCheckHandler{
@Override
public Result handler(Product param) {
System.out.println("库存校验开始...");
//降级:如果配置了降级,则跳过此处理器执行下一个处理器
if(super.config.isDown()){
System.out.println("库存校验降级通过");
return super.next(param);
}
if (param.getStock()<=0) {
return Result.failure("库存已空");
}
System.out.println("库存校验通过");
return super.next(param);
}
}
5. 处理器执行链路类
public class HandlerClient {
public static Result executeChain(AbstractCheckHandler handler, Product param){
Result handlerResult = handler.handler(param);
if (!handlerResult.isSuccess()) {
System.out.println("责任链执行失败,返回: "+handlerResult.getMsg());
return handlerResult;
}
return Result.success();
}
}
6. 测试
@SpringBootTest
class ApplicationTests {
@Autowired
private Map<String, AbstractCheckHandler> handlerMap;
@Test
public void createProduct(){
Product param = Product.builder().skuId(123L).price(new BigDecimal(50)).stock(1).build();
Result paramCheckResult = this.paramCheck(param);
if (!paramCheckResult.isSuccess()) {
System.out.println(paramCheckResult.toString());
return;
}
//执行保存商品
System.out.println("成功");
}
/**
* 使用责任链校验参数
* @param param
* @return
*/
private Result paramCheck(Product param) {
//模拟从配置中心获取配置检验链路
String configJson = "{\"handler\":\"nullCheckHandler\",\"down\":true,\"next\":{\"handler\":\"priceCheckHandler\",\"next\":{\"handler\":\"stockCheckHandler\",\"next\":null}}}";
//转成Config对象
ProductCheckHandlerConfig handlerConfig = JSONUtil.toBean(configJson, ProductCheckHandlerConfig.class);
AbstractCheckHandler handler = this.getHandler(handlerConfig);
return HandlerClient.executeChain(handler,param);
}
/**
* 获取处理器
* @param config
* @return
*/
private AbstractCheckHandler getHandler(ProductCheckHandlerConfig config) {
if (config == null) {
return null;
}
//配置错误
if (config.getHandler().isEmpty()) {
return null;
}
//配置了不存在的处理器
AbstractCheckHandler abstractCheckHandler = handlerMap.get(config.getHandler());
if (abstractCheckHandler == null) {
return null;
}
//处理器设置配置config
abstractCheckHandler.setConfig(config);
abstractCheckHandler.setNextHandler(this.getHandler(config.getNext()));
return abstractCheckHandler;
}
}
结果: