责任链模式实现规则校验

1、项目中责任链模式实战

我们使用责任链模式实现对订单中参数的校验,首先校验订单id是否为空,然后校验下单人是否为空,最后检验收获地址是否为空。业务的流程图如下所示:

针对上述的业务,我们使用责任链的模式来实现这个功能:

(1)定义一个责任链的接口

java 复制代码
public interface OrderCheckHandler {
	/**
	 * 当前的订单检测实现逻辑
	 * @param orderCheckParam
	 */
	void check(OrderCheckParam orderCheckParam);

	/**
	 * 设置下一个检测的实现逻辑
	 * @param nextOrderCheckHandler
	 * @return
	 */
	OrderCheckHandler setNext(OrderCheckHandler nextOrderCheckHandler);
}

(2)责任链中的公共逻辑的抽取

java 复制代码
public abstract class BaseCheckOrderHandler implements OrderCheckHandler {
    private OrderCheckHandler nextOrderCheckHandler;
    @Override
    public void check(OrderCheckParam orderCheckParam) {
        this.currentCheck(orderCheckParam);
        if(Objects.nonNull(nextOrderCheckHandler)){
            nextOrderCheckHandler.check(orderCheckParam);
        }
    }
    /**
     * 具体的实现逻辑
     *
     */
    protected abstract void currentCheck(OrderCheckParam orderCheckParam);
    @Override
    public OrderCheckHandler setNext(OrderCheckHandler nextOrderCheckHandler) {
        this.nextOrderCheckHandler = nextOrderCheckHandler;
        return this.nextOrderCheckHandler;
    }
}

(3)具体的检验逻辑(继承公共逻辑)

java 复制代码
-- 订单id校验
public class OrderIdCheckHandler extends BaseCheckOrderHandler {
	@Override
	protected void currentCheck(OrderCheckParam orderCheckParam) {
        if(orderCheckParam.getOrderId() == null){
            throw new RuntimeException("订单id为空");
        }
	}
}
-- 用户校验
public class BuyerCheckHandler extends BaseCheckOrderHandler {
	@Override
	protected void currentCheck(OrderCheckParam orderCheckParam) {
        if(orderCheckParam.getBuyer() == null){
            throw new RuntimeException("用户不可以为空");
        }
	}
}
-- 地址校验
public class AddressCheckHandler extends BaseCheckOrderHandler {
	@Override
	protected void currentCheck(OrderCheckParam orderCheckParam) {
        if(orderCheckParam.getAddress() == null){
            throw new RuntimeException("用户地址不可以为空");
        }
	}
}

(4)使用spring将业务逻辑串联起来

java 复制代码
@Configuration
public class OrderCheckConfig {
	@Bean
    public BuyerCheckHandler buyerCheckHandler(){
        return new BuyerCheckHandler();
    }

    @Bean
    public OrderIdCheckHandler checkOrderIdHandler(){
        return new OrderIdCheckHandler();
    }

    @Bean
    public AddressCheckHandler addressCheckHandler(){
        return new AddressCheckHandler();
    }

    //设置责任链得执行链路顺序
    @Bean
    public OrderCheckHandler orderCheckHandler(){
        OrderIdCheckHandler orderIdCheckHandler = this.checkOrderIdHandler();
        orderIdCheckHandler.setNext(this.buyerCheckHandler()).setNext(this.addressCheckHandler());
        return orderIdCheckHandler;
    }
}

(5)service调用责任链的

java 复制代码
@Service
public class OrderService {

    @Resource
    private OrderCheckHandler orderCheckHandler;

    public String checkOrderParam(OrderCheckParam param){
        orderCheckHandler.check(param);
        return "success";
    }
}

(6)controller逻辑

java 复制代码
@RestController
@RequestMapping("/test")
public class ZeRenLianTestController {

    @Resource
    private OrderService orderService;

    @GetMapping("/checkOrder")
    public String checkOrder(){
        OrderCheckParam orderCheckParam = new OrderCheckParam();
        orderCheckParam.setAddress("123");
        orderCheckParam.setOrderId("1235689");
        return orderService.checkOrderParam(orderCheckParam);
    }
}

如果现在需要增加一种校验(如增加订单物流的校验),此时我们只需要增加一个业务的实现类,然后在spring的配置将这个业务实现类加入到责任链逻辑上就可以了。

总结:

(1)需要保证责任链的结构清晰、避免创建过长的链,进而提升执行的性能。

(2)每个业务应该具有单一职责,每个对象专注于处理自己的逻辑。

(3)责任链模式使用的典型场景是多个对象处理同一个请求,如OA审批、参数的校验、日志记录器链等等。

相关推荐
我命由我123452 小时前
Kotlin 数据容器 - List(List 概述、创建 List、List 核心特性、List 元素访问、List 遍历)
java·开发语言·jvm·windows·java-ee·kotlin·list
武子康4 小时前
Java-80 深入浅出 RPC Dubbo 动态服务降级:从雪崩防护到配置中心秒级生效
java·分布式·后端·spring·微服务·rpc·dubbo
YuTaoShao7 小时前
【LeetCode 热题 100】131. 分割回文串——回溯
java·算法·leetcode·深度优先
源码_V_saaskw7 小时前
JAVA图文短视频交友+自营商城系统源码支持小程序+Android+IOS+H5
java·微信小程序·小程序·uni-app·音视频·交友
超浪的晨7 小时前
Java UDP 通信详解:从基础到实战,彻底掌握无连接网络编程
java·开发语言·后端·学习·个人开发
双力臂4048 小时前
Spring Boot 单元测试进阶:JUnit5 + Mock测试与切片测试实战及覆盖率报告生成
java·spring boot·后端·单元测试
Edingbrugh.南空8 小时前
Aerospike与Redis深度对比:从架构到性能的全方位解析
java·开发语言·spring
QQ_4376643149 小时前
C++11 右值引用 Lambda 表达式
java·开发语言·c++
永卿0019 小时前
设计模式-迭代器模式
java·设计模式·迭代器模式
誰能久伴不乏9 小时前
Linux如何执行系统调用及高效执行系统调用:深入浅出的解析
java·服务器·前端