责任链设计模式

责任链设计模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许多个对象都有机会处理请求,从而避免请求的发送者与接收者之间的耦合。责任链模式通过将这些对象连成一条链,并沿着这条链传递请求,直到某个对象处理它为止。

1. 基础代码示例

/**
     * cyt 20240814 根据参数查找运费模板
     * @param waybillDTO 
     * @return 运费模板实体
     */
    private CarriageEntity findCarriage(WaybillDTO waybillDTO) {
        // 1. 如果是同城
       。。。处理逻辑。。。
                return carriageEntity;
            
   
        // 2. 如果是同省
        。。。处理逻辑。。。
                return carriageEntity;

        // 3. 如果是经济区
        。。。处理逻辑。。。
                return carriageEntity;

        // 4. 跨省
        。。。处理逻辑。。。
                return carriageEntity;
    }

在上述的代码中,判断了很多种情况,如果后续要再增加不同类型的模板或者调整模板之间的优先级,就必须改动代码,所以这样的实现扩展性并不好,也不够灵活。这里可以通过【责任链设计模式】来优化。

之所以采用【责任链】模式,是因为在查找模板时,不同的模板处理逻辑不同,并且这些逻辑组成了一条处理链,有开头有结尾,只要能找到符合条件的模板即结束。

2.责任链模式优化代码

2.1 定义处理链抽象类

1. nextHandler:记录下一个处理器

2. setNextHandler:给nextHander赋值

3. doHandler:抽象方法,由具体的处理器实现,用于处理运费模板的查找逻辑

4、doNextHander:已经实现好的,调用下一个处理器的方法

/**
 * 运费模板处理链的抽象定义
 */
public abstract class AbstractCarriageChainHandler {

    private AbstractCarriageChainHandler nextHandler;

    /**
     * 执行过滤方法,通过输入参数查找运费模板
     *
     * @param waybillDTO 输入参数
     * @return 运费模板
     */
    public abstract CarriageEntity doHandler(WaybillDTO waybillDTO);

    /**
     * 执行下一个处理器
     *
     * @param waybillDTO     输入参数
     * @param carriageEntity 上个handler处理得到的对象
     * @return
     */
    protected CarriageEntity doNextHandler(WaybillDTO waybillDTO, CarriageEntity carriageEntity) {
        if (nextHandler == null || carriageEntity != null) {
            //如果下游Handler为空 或 上个Handler已经找到运费模板就返回
            return carriageEntity;
        }
        return nextHandler.doHandler(waybillDTO);
    }

    /**
     * 设置下游Handler
     *
     * @param nextHandler 下游Handler
     */
    public void setNextHandler(AbstractCarriageChainHandler nextHandler) {
        this.nextHandler = nextHandler;
    }
}

2.2 实现具体的处理器

定义顺序,继承处理链抽象类,实现doHander抽象方法,在doHander最后返回doNextHander。

2.2.1 同城寄

/**
 * 同城寄
 */
@Order(100) //定义顺序
@Component
public class SameCityChainHandler extends AbstractCarriageChainHandler {


    @Override
    public CarriageEntity doHandler(WaybillDTO waybillDTO) {
        。。。处理逻辑。。。
        return doNextHandler(waybillDTO, carriageEntity);
    }
}

2.2.2  省内寄

/**
 * 省内寄
 */
@Order(200) //定义顺序
@Component
public class SameProvinceChainHandler extends AbstractCarriageChainHandler {

   
    @Override
    public CarriageEntity doHandler(WaybillDTO waybillDTO) {
       。。。处理逻辑。。。
        return doNextHandler(waybillDTO, carriageEntity);
    }
}

2.2.3 经济区互寄

/**
 * 经济区互寄
 */
@Order(300) //定义顺序
@Component
public class EconomicZoneChainHandler extends AbstractCarriageChainHandler {

    
    @Override
    public CarriageEntity doHandler(WaybillDTO waybillDTO) {    
        。。。处理逻辑。。。
        return doNextHandler(waybillDTO, carriageEntity);
    }
}

2.2.4 跨省寄

/**
 * 跨省
 */
@Order(400) //定义顺序
@Component
public class TransProvinceChainHandler extends AbstractCarriageChainHandler { 

    @Override
    public CarriageEntity doHandler(WaybillDTO waybillDTO) {
       。。。处理逻辑。。。
        return doNextHandler(waybillDTO, carriageEntity);
    }
}

2.3 组装处理链

 组装处理链,按照@Order注解中的值,由小到大排序。

/**
 * 查找运费模板处理链 @Order注解指定handler顺序
 */
@Component
public class CarriageChainHandler {

    /**
     * 利用Spring注入特性,按照 @Order 从小到达排序注入到集合中
     */
    @Resource
    private List<AbstractCarriageChainHandler> chainHandlers;

    private AbstractCarriageChainHandler firstHandler;

    /**
     * 组装处理链
     */
    @PostConstruct // Spring自动调用该方法
    private void constructChain() {
        if (CollUtil.isEmpty(chainHandlers)) {
            throw new SLException("not found carriage chain handler!");
        }
        //处理链中第一个节点
        firstHandler = chainHandlers.get(0);
        for (int i = 0; i < chainHandlers.size(); i++) {
            if (i == chainHandlers.size() - 1) {
                //最后一个处理链节点
                chainHandlers.get(i).setNextHandler(null);
            } else {
                //设置下游节点
                chainHandlers.get(i).setNextHandler(chainHandlers.get(i + 1));
            }
        }
    }

    public CarriageEntity findCarriage(WaybillDTO waybillDTO) {
        //从第一个节点开始处理
        return firstHandler.doHandler(waybillDTO);
    }

}

@PostConstruct:这个注解标注的方法会在 Spring 完成依赖注入后自动调用,用来初始化责任链。

3. 总结

调用carriageChainHandler.findCarriage(waybillDTO)方法和直接调用基础代码示例中的findCarriage(waybillDTO)方法,效果相同,完成了责任链模式的代码优化。

通过这种设计,如果将来需要新增处理逻辑或调整处理顺序,只需新建处理器类或调整 @Order 注解的值,而无需修改现有的代码结构,极大地提高了代码的可维护性和扩展性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cyt涛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值