流水线模式

背景

最近工作中有这么一个需求,我们系统正常通过消息队列同步上游的订单数据,但是在一些极端情况会有少量数据出现错误,这个时候就需要人为手动去修复。通过上游提供的接口拉取一个订单的全量数据,然后插入或者更新我们系统的数据。订单的数据包括商品信息,地址信息,支付信息等等。一般可能会写一个方法,然后拿出每种信息,做不同的处理。

问题及优化

上面那样写代码不会有任何问题,依然可以正常执行。但是有这样一个问题,例如某一天,来了一个需求需要再同步配送信息,这个时候按照上面那样写就要改的原来的代码,似乎不太符合设计模式的开闭原则。这里可以这样优化,定义一个处理这个全量信息的接口,然后不同的信息放到不同的信息处理类中去实现,这样需要多同步信息的时候,只要多写一个信息处理类就行了。

代码

首选定义一个订单全量信息类,包含订单信息,商品信息,地址信息

@Data
public class OrderInfos {
    private Order order;
    private List<Goods> goodsList;
    private Address address;

    public static class Order{}
    public static class Goods{}
    public static class Address{}
}

然后定义一个信息处理接口,就一个处理全量信息的方法

public interface InfoProcessor {
    boolean processorInfo(OrderInfos infos);
}

接下来分别定义三个不同信息处理的实体类,实现信息处理接口,每种信息的具体处理方式可以在实体类中实现。
订单信息处理类:

public class OrderInfoProcessor implements InfoProcessor {
    @Override
    public boolean processorInfo(OrderInfos infos) {
        System.out.println("处理订单信息"+infos.getOrder());
        return true;
    }
}

商品信息处理类:

public class GoodsInfoProcessor implements InfoProcessor {
    @Override
    public boolean processorInfo(OrderInfos infos) {
        System.out.println("处理商品信息"+infos.getGoodsList());
        return true;
    }
}

地址信息处理类:

public class AddressInfoProcessor implements InfoProcessor {
    @Override
    public boolean processorInfo(OrderInfos infos) {
        System.out.println("处理地址信息"+infos.getAddress());
        return true;
    }
}

然后定义一条流水线,把这些具体信息处理类串起来,这个类中定义了一个静态的处理类列表,用来存放信息处理类,还有一个处理方法就是遍历列表,把信息交给列表中的每个信息处理类去处理。

public class Pipeline {
    public static List<InfoProcessor> actualProcessorList = new ArrayList<>();

    public void processorInfo(OrderInfos orderInfos){
        for (InfoProcessor infoProcessor : actualProcessorList) {
            infoProcessor.processorInfo(orderInfos);
        }
    }
}

具体使用

public class Application {
    public static void main(String[] args) {
        Pipeline.actualProcessorList.add(new OrderInfoProcessor());
        Pipeline.actualProcessorList.add(new GoodsInfoProcessor());
        Pipeline.actualProcessorList.add(new AddressInfoProcessor());
        Pipeline pipeline = new Pipeline();

        OrderInfos orderInfos = new OrderInfos();

        pipeline.processorInfo(orderInfos);
    }
}

首选是初始化流水线列表,如果使用spring可以直接通过注入的方式初始化。然后就是调用初始化方法。

总结

这样写似乎类会多出来很多,代码量甚至增加了,但是这样写就基本达到了开闭原则。例如需要对商品信息的处理过程进行修改,只要修改商品信息处理类就行了,其他信息处理类不用改的,清晰明了。再或者像开始说的需要新增同步配送信息,只要新增一个配送信息处理类就可以了,无需改的以前的代码。

一些思考

其实代码中的流水线并不像生活中的那样,在前后逻辑没有关联的情况下,也就是说后一步的操作不依赖前一步,前后的操作完全可以通过多线程并行去处理,大大提高运行的效率。例如上面对订单信息、商品信息、地址信息完全可以多线程并行处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值