责任链模式+建造者模式让你业务“香”起来

1,021 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

写在前面

关注过我的伙伴都知道 我以前出过一个设计模式专栏(不知道的的朋友可以点击我头像查看专栏),欢迎指导评论。

今天之所以再拿起来讲讲,是因为这里面涉及到的知识点,其实挺多的,可能设计模式都会有一个通病:

那就是如何将业务bean统一交给Spring管理,否则无法引用。接下来给大家举个例子。今天我想搞一个讨论会,大家尝试解决 并在评论区我们讨论下,谁的方案更好。 我也学习下,因为我的方案不是最好的。所以先不粘贴出来。希望大家理解

抛出问题

比如我们一个下单业务(怎么简单怎么来):

第一步:接口参数校验

第二步:创建支付订单

第三步,请求支付服务获取支付信息

最终方案是要用责任链的模式处理这几个业务块,这样达到解藕目的,新的业务请求再进来,只需要加类就行,比如到时候要来个减库存操作。直接加类即可。不影响参数校验模块,创建订单模块,只需要按照相应顺序链式调用即可,一传二,二传三,最终执行完成

好,责任链的东西 就说这么多(点击我头像专栏可以详细看设计模式),本节重点是如何解决bean加载问题。

下面Hanler类是责任链处理类,OrderPayCheckHandler 是参数校验类。OrderPayResultHandler是业务处理完毕类

image.png

代码案例:


/**
 * 定义责任链处理类
 * @Date 2021/4/14 7:26 下午
 * @Author yn
 */
@Component
public abstract class Handler<T> {

    protected Handler next;


    public void next(Handler next){
        this.next = next;
    }


    public abstract ResponseBO doHandler(OrderPayDto orderPayDto, NextProcessParam nextParam);


    public static class Bulider<T>{

        private Handler<T> head; //责任链头部

        private Handler<T> tail; //责任链尾


        public Bulider<T> addHandler(Handler handler){

            if (this.head == null){
                this.head = this.tail = handler;

                return this;
            }
            this.tail.next(handler);
            this.tail = handler;
            return this;
        }

        public Handler<T> build(){return this.head;}
    }
}

上面这段代码很好理解,那就是处理这个链式调用的。下面是开始校验模块

/**
 * 校验业务处理类
 * @Date 2021/10/18 6:29 下午
 * @Author yn
 */
@Service
public class OrderPayCheckHandler extends Handler{


    private Logger logger = LoggerFactory.getLogger(OrderPayCheckHandler.class);



    //orderPayService 能拿到吗?
    @Autowired
    private OrderPayService orderPayService;


    @Override
    public ResponseBO doHandler(OrderPayDto orderPayDto, NextProcessParam nextParam) {
        int platformCardValue = 0 ,carOrderNeedPay = 0,couponValue = 0,couponOrderNeedValue = 0;

        //返回数据体
        JSONObject resJson = new JSONObject();
        resJson.put("needPay",true);//默认需要支付


        //这里会不会报空指针异常
        OrderRecord thsOrderRecord = orderPayService.getByOrderNo(orderPayDto.getOrderNo());
        
        if (thsOrderRecord == null){
            resJson.put("needPay",false);
            resJson.put("orderNo",thsOrderRecord.getOrderNo());
            resJson.put("msg","订单不存在!");
            return ResponseBO.Builder.init().setData(resJson).build();
        }
        //订单状态
        if(OrderRecord.getOrderStatus() == 1){//支付已完成
            resJson.put("needPay",false);
            resJson.put("orderNo",orderRecord.getOrderNo());
            return ResponseBO.Builder.init().setData(resJson).build();
        }

        //getpaycode
        String payCode = "pay_code";


        //贯穿整个业务记录的bizcode
        String bizCode= StringUtil.randomOrderNo("CM");//业务订单标示

        //组装下个链式所需参数
        NextProcessParam nextProcessParam = NextProcessParamBuilder.build().ofOrderPay(payCode,bizCode);

        //往下个调用传参
        return next.doHandler(orderPayDto,nextProcessParam);
    }
}

模拟调用:


/**
 * 统一支付
 * @param orderPayDto
 * @return
 */
@RequestMapping(value = "testApi",method = RequestMethod.POST, produces = "application/json")
public ResponseBO testApi(@RequestBody OrderPayDto orderPayDto){
    Handler.Bulider bulider = new Handler.Bulider();
    Handler handler = bulider.addHandler(new OrderPayCheckHandler()).addHandler(new OrderPayResultHandler()).build();
    return handler.doHandler(orderPayDto,new NextProcessParam());
}

问题点:

OrderPayCheckHandler类中无法引入OrderPayService,报空指针

这就是今天要说的 ,那就是abstract 处理流程中 无法注入bean,大家有没有好的解决方案。在你们的实战中是怎么解决的?欢迎大家评论区交流。我第二天会把我的方案给放出来。