Java设计模式 - 管道模式

news2024/11/20 21:20:42

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

定义

管道模式使用有序的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里面一般不会写笔记复杂的逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/76798.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

以智能视觉驱动智慧出行,看中科创达如何持续深耕汽车市场

当前&#xff0c;360全景环视&#xff08;AVM&#xff09;正在往丰富的ADAS功能、透明底盘功能、不同等级的自动泊车功能等领域拓展&#xff0c;全景环视市场的多元化增长路径已经全面开启。 高工智能汽车研究院监测数据显示&#xff0c;2022年1-9月中国市场&#xff08;不含进…

工厂应该如何批量打印送货单和产品标签

01基本需求 图1是公司的出货明细表&#xff0c;要求按图2的样式批量打印标签&#xff0c;然后将标签张贴在产品包装箱上&#xff0c;否则客户不收货。 其中A7单元格用于存放条形码&#xff0c;条形码用于存放产品的订单号。 图1 订单表 图2 标签模板样式 02操作步骤 利用E…

【2023春招Java岗面试】 90% 会问到的 200+Java 面试题汇总(含答案解析),一定要抓住重点

前言 很多朋友问&#xff0c;有没有整理今年的一些面试题&#xff0c;最近抽时间整理了一份 Java 面试题。或许这份面试题还不足以囊括所有 Java 问题&#xff0c;但有了它&#xff0c;我相信足以应对目前市面上绝大部分的 Java 面试了&#xff0c;因为这篇文章不论是从深度还…

简单讲解Linux PSCI框架

说明&#xff1a; Kernel版本&#xff1a;4.14ARM64处理器使用工具&#xff1a;Source Insight 3.5&#xff0c; Visio 1. 介绍 PSCI, Power State Coordination Interface&#xff0c;由ARM定义的电源管理接口规范&#xff0c;通常由Firmware来实现&#xff0c;而Linux系统可…

014 | 探讨京族民间传说中的海洋文化特质 | 大学生创新训练项目申请书 | 极致技术工厂

&#xff08;一&#xff09;研究目的 京族是我国56个民族中唯一一个生活在海边的少数民族&#xff0c;这一特殊的少数民族位于我国西南沿海边陲&#xff0c;有着独具特色的海洋文化。渔民的海神信仰、特殊的舞蹈和乐器积淀了京族丰富的历史文化。以海洋地域为背景、世世代代以海…

神经网络的应用(分类和预测)——python

神经网络的应用一.数据预处理 ​ 由于神经网络输入数据的范围可能特别大&#xff0c;导致神经网络收敛慢、训练时间长。因此在训练神经网络前一般对数据进行预处理(不妨假设这里的指标都是效益型的(即都是正项指标))&#xff0c;一种重要的预处理的处理手段是归一化处理&#…

CMake中set_property/get_property的使用

CMake中的set_property命令用于在给定作用域(scope)内设置命名属性&#xff0c;其格式如下&#xff1a; set_property(<GLOBAL |DIRECTORY [<dir>] |TARGET [<target1> ...] |SOURCE [<src1> ...][DIRECTORY <…

小程序AP配网和AK配网教程(开源)

小程序AP配网和AK配网教程&#xff08;开源&#xff09; 一、 Airkiss配网的实现方式 ​ Airkiss配网我们采用插件的形式&#xff0c;非常简单方便。感谢半颗心脏大佬的开源插件。 1. Airkiss 简介 AirKiss是微信硬件平台为Wi-Fi设备提供的微信配网、局域网发现和局域网通讯…

将两个数组进行竖直(水平)方向的拼接 vstack()和hstack()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 将两个数组进行竖直(水平)方向的拼接 vstack()和hstack() [太阳]选择题 以下关于Python代码的选项说法错误的一项是? import numpy as np myArray1np.array([1,2,3]) print("【…

主线程与分支线程的访问、修改

任务1&#xff1a;定义一个全局变量 int a10&#xff0c;主线程能否访问到&#xff0c;分支线程能否访问到&#xff1b; 任务2&#xff1a;分支线程中修改上述的a 20, 问主线程中访问该a&#xff0c;是10还是20; 任务3&#xff1a;在主线程定义一个局部变量int b1&#x…

代码随想录刷题day59 503.下一个更大元素II;42. 接雨水

代码随想录刷题day59 503.下一个更大元素II&#xff1b;42. 接雨水 单调栈的一些应用。 503.下一个更大元素II 503. 下一个更大元素 II - 力扣&#xff08;Leetcode&#xff09; 还是下一个最大元素&#xff0c;主要是掌握循环数组中利用%取余的这个操作&#xff0c;在循环…

微服务框架 SpringCloud微服务架构 28 数据同步 28.1 同步方案分析

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构28 数据同步28.1 同步方案分析28.1.1 数据同步问题分析28.1.2 总结28 数据…

Yarn增加新队列-----hive向Yarn提交任务后,Hadoop再次向Yarn提交任务阻塞

博学之&#xff0c;审问之&#xff0c;慎思之&#xff0c;明辨之&#xff0c;笃行之&#x1f3c2; hive on spark搭建好后&#xff0c;任务提交会有问题&#xff0c;因为通过hive会话提交的任务一直存在且不会结束&#xff08;除非关掉这个hive会话&#xff09;&#xff0c;根本…

微服务框架 SpringCloud微服务架构 27 自动补全 27.4 修改酒店索引库数据结构

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构27 自动补全27.4 修改酒店索引库数据结构27.4.1 案例27 自动补全 27.4 修…

Java中的Unsafe的介绍与使用

Java中的Unsafe的介绍与使用 相关文章 美团-Unsafe JavaGuide-Unsafe 什么是Unsafe&#xff1f;&#xff1f;&#xff1f; 如何创建Unsafe对象&#xff1f; 通过反射获取Unsafe对象&#xff08;案例&#xff09; Unsafe功能简介 1. 内存操作 2. 内存屏障 3. 对象操…

猿如意中的【Sublime Text】开发工具详情介绍

目录 一、工具名称 二、下载安装渠道 2.1 什么是猿如意&#xff1f; 2.2 如何下载猿如意&#xff1f; 2.3 如何在猿如意中下载Sublime Text &#xff1f; 三、sublime text介绍 四、软件安装过程 五、软件界面 六、sublime text功能特点介绍 七、sublime tex…

【UDS】ISO15765-2之协议数据单元

文章目录简介结构格式分类1.单帧SF2.首帧FF3.流控帧FC4.连续帧CF总结->返回总目录<- 简介 网络层协议数据单元&#xff08;N_PDU&#xff0c;Network_Protocol Data Unit&#xff09;。可以理解成是一种规范协议。而汽车电子中通信的报文格式就是以PDU为传输单元&#…

COM通信栈

基于 AUTOSAR 架构的软件层概述 根据分层AUTOSAR 架构&#xff0c;软件开发是按照以下模块&#xff08;层&#xff09;&#xff08;自下而上&#xff09;实现的&#xff1a; 基本软件 (BSW) 层——这包括以下内容&#xff1a; 微控制器抽象层 (MCAL)电子控制单元 (ECU) 抽象层…

海关统计:全国、各省、各城市进出口贸易数据+地级市进出口贸易、对外贸易数据及进出口月度数据

&#xff08;1&#xff09;2004-2019年地级市进出口贸易总额数据 1、数据来源&#xff1a;各城市统计年鉴、省份统计年鉴 2、时间跨度&#xff1a;2004-2019 3、区域范围&#xff1a;全国287个地级市 4、指标说明&#xff1a; 人民币和美元两种计价方式&#xff0c;人民币…

【应用层】P2P、DNS、递归查询、迭代查询、FTP、电子邮件系统、万维网和HTTP

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录应用层---网络层点到点----传输层端到端------应用层为应用提供多样服务---------功能&#xff1a;文件传输、访问、管理ftp---电子邮件smtp---虚拟终端http-让个人用户直接与大型计算机联系&#xff0c;不必…