Java设计模式 - 管道模式

管道模式是责任链模式的常用变种之一,但是管道模式和责任链模式有一个关键的区别,在看一些博客的时候并没有体现出来出来,很多人都把责任链模式当做管道模式来说。

定义

管道模式使用有序的Stage(或者Handler)来顺序的处理一个输入值,每个处理过程被看做一个阶段。 但是每一个阶段都以来上一个阶段的输出。

如果不依赖上一个阶段的输出结果,那么使用责任链模式即可。责任链模式的每个处理器互相独立,不依赖别的处理器结构。

做个比喻:

  • 管道模式可用看做是富士康流水线,每个环节都依赖上个环节的输出

  • 责任链模式类似于招标,下发任务,谁有能力谁处理,不需要关心其他人;

当然设计模式肯定是可以混用的,都是使用两个模式也是OK的。

需求中的案例

在负责的项目中,一般我们的业务模型会越来越复杂,想要做一件事需要和多个模型交互;

而模型之间又存在依赖关系,一个模型依赖另外一个模型的某个属性;

每个模型都有需要校验的部分,连续多个之后,我们的代码结构就会变得比较长。

比如:

输入某个任务:
1、检查任务是否有其他导出渠道。   查出渠道模型;
2、检查渠道是否审核通过;

3、检查渠道审核通过之后是否有导出记录;  查记录模型;
4、检查导出记录状态是否符合预期;

复制代码

3,4是以来1,2的结果的,但是都在一起写,目前还不是很长,但是如果继续增加逻辑就会变得更长。

如果使用的管道模式的话:

Code

定义阶段

管道模式的输入依赖上一个阶段的输出,因此入参和出参都需要考虑进去。


public interface PipeStage<I,O> {

    /**
     * 通过异常来终止观点的执行过程
     */
    class StepException extends RuntimeException {
        public StepException(Throwable t) {
            super(t);
        }
    }

    O process(I input);
}

复制代码

定义管道

管道可以不断的添加新的阶段,并且每个阶段依赖上个阶段的输出


import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Pipeline<I, O> {
    private final PipeStage<I, O> currentHandler;

    Pipeline(PipeStage<I, O> currentHandler) {
        this.currentHandler = currentHandler;
    }

    <K> Pipeline<I, K> addHandler(PipeStage<O, K> newHandler) {
        log.info("addHandler");
        PipeStage<I, K> ikHandler = input -> newHandler.process(currentHandler.process(input));
        return new Pipeline<>(ikHandler);
    }

    O execute(I input) {
        return currentHandler.process(input);
    }

}
复制代码

定义管道阶段实现

使用刚才的例子:


import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class AbstractHandler {

    @Data
    static class ChannelConfig {
        /**
         * 渠道Id
         */
        private String id;

        /***
         * 审判状态
         */
        private int applyStatus;
    }

    @Data
    static class ChannelExportRecord{
        private String configId;

        /**
         * 导出状态
         */
        private int exportStatus;
    }

    static class CheckApprovedHandler implements PipeStage<String, ChannelConfig> {

        @Override
        public ChannelConfig process(String input) {
            // ... 此处查询input中的值,判断渠道配置
            log.info("apprvoed {}",input);

            ChannelConfig channelConfig = new ChannelConfig();
            return channelConfig;
        }
    }

    public static class CheckRecordSuccessHandler implements PipeStage<ChannelConfig, ChannelExportRecord> {

        @Override
        public ChannelExportRecord process(ChannelConfig input) {
            log.info("record passed {}",input);
            return new ChannelExportRecord();
        }
    }


}
复制代码

使用管道

把我们刚才的代码组合起来:

Slf4j
public class PipeDemo {

    public static void main(String[] args) {
        Pipeline<String, ChannelExportRecord> handler = new Pipeline<>(
            new CheckApprovedHandler())
            .addHandler(new CheckRecordSuccessHandler());

        //String filters = (String)handler;
        log.info("start Handler");
        ChannelExportRecord record = handler.execute("导出配置Id");
        log.info("result {}", JSON.toJSONString(record));
    }
}

复制代码

运行结果

总结

1、每个管道阶段在实现的时候是互相独立的;这样也更方便单测 2、管道阶段在使用的时候会组合成一个流水线管道,每个阶段的输入和输出有一定依赖关系,上个阶段要为下个阶段准备好数据。 3、设计模式的通用好处:代码可读性,维护性提升;当然管道模式有点像Java的Stream,只是Stream里面一般不会写笔记复杂的逻辑。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java项目中,设计模式非常重要,几乎无处不在。Java本身的设计中就融入了设计模式的思想,包括AWT、JDBC、集合类、IO管道和Web框架等。虽然篇幅有限,无法详细讲解每一个设计模式,但我会尽力在有限的空间内清楚地介绍它们。 在Java项目中常见的设计模式有观察者模式、访问者模式和工厂模式等。 观察者模式定义了一种一对多的依赖关系,当被观察对象的状态发生变化时,所有观察者都会收到通知并进行相应的更新。观察者接口(Observer)中通常包含一个update()方法,用于更新观察者的状态。 访问者模式用于封装一些作用于某个对象结构中各个元素的操作,可以在不改变这些元素的类的前提下,定义新的操作。访问者接口(Visitor)中通常包含一个visit()方法,用于访问具体的元素。 工厂模式是一种创建对象的设计模式,它使用工厂方法来处理创建对象的问题,而不是由客户端直接new一个对象。工厂模式中常见的接口是提供者接口(Provider),它定义了一个produce()方法,用于创建对象。 除了观察者模式、访问者模式和工厂模式Java项目中还有很多其他的设计模式,如单例模式、策略模式、装饰者模式等。每个设计模式都有自己的用途和适用场景,可以根据项目需求选择合适的设计模式来提高代码的可维护性和可扩展性。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值