软件架构风格系列(3):管道 - 过滤器架构


文章目录

  • 前言
  • 一、从生活场景到架构原理,看懂管道 - 过滤器的核心逻辑
    • (一)什么是管道 - 过滤器架构?
    • (二)核心组件拆解
  • 二、架构设计图:一图看懂管道 - 过滤器架构全貌
  • 三、Java 示例代码:手把手教你实现管道 - 过滤器架构
    • (一)定义过滤器接口
    • (二)实现具体过滤器
    • (三)实现管道类
    • (四)使用示例
  • 四、管道 - 过滤器架构的优势与适用场景
    • (一)核心优势
    • (二)适用场景
  • 五、使用管道 - 过滤器架构的注意事项
  • 总结

前言

在互联网技术的高速发展中,系统架构的设计直接影响着软件的性能与可维护性。当你在使用 ETL 工具处理海量数据,或是在编译器中实现代码的层层解析时,背后往往都有一个低调却强大的架构风格在支撑 —— 管道 - 过滤器架构。作为一个在系统架构领域摸爬滚打多年的老湿机,今天就来和大家深度剖析这个 “数据处理利器”,带你从理论到实践吃透它!

一、从生活场景到架构原理,看懂管道 - 过滤器的核心逻辑

(一)什么是管道 - 过滤器架构?

**管道 - 过滤器架构,顾名思义,其灵感来源于现实生活中的流水线作业。**想象一下工厂里的汽车组装流水线,每个工位的工人负责特定的组装步骤,零件依次从一个工位传递到下一个工位,最终完成汽车的组装。

在软件架构中,“过滤器” 就如同流水线上的工位工人,负责对数据进行特定处理;“管道” 则是连接这些工位的传送带,负责将数据从一个过滤器传输到下一个过滤器。

每个过滤器都有明确的输入和输出,它们相互独立,只专注于自己的处理任务,如数据清洗、格式转换、逻辑校验等。数据通过管道在各个过滤器之间流动,形成一条完整的数据处理链路。

例如,在一个日志分析系统中,数据首先经过 “日志采集过滤器” 收集原始日志,然后通过管道传递给 “日志清洗过滤器” 去除无效信息,接着再传递给 “日志分析过滤器” 提取关键数据,最后输出分析结果。

(二)核心组件拆解

过滤器(Filter):过滤器是无状态的处理单元,它只根据输入数据产生输出,不会受到其他过滤器或系统状态的影响。比如在编译器中,“词法分析过滤器” 会将源代码分解成一个个单词,不依赖后续的语法分析过程。

管道(Pipe):管道负责数据的传输,它可以是同步传输,也可以是异步传输,甚至支持数据缓冲。像 Unix 系统中的管道符 “|”,就是典型的管道实现,它能将一个命令的输出作为另一个命令的输入。在软件系统中,消息队列(如 Kafka)也可以充当管道的角色,实现数据在不同过滤器之间的异步传递。

数据流(Data Flow):数据流决定了数据在过滤器之间的流动方向和顺序。它支持增量处理,即前一个过滤器无需完全处理完所有数据,就可以将部分结果传递给下一个过滤器,从而提高整体处理效率。

二、架构设计图:一图看懂管道 - 过滤器架构全貌

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这张架构设计图中,最上方的 A 节点代表数据源,数据从这里开始进入处理流程。紧接着是一系列的过滤器(B - F),每个过滤器负责不同的数据处理任务。数据通过管道(管道 1 - 管道 3)在过滤器之间有序流动,最终到达数据目标 G,完成整个数据处理过程。通过这张图,我们可以清晰地看到管道 - 过滤器架构中各组件之间的关系和数据的流向。

三、Java 示例代码:手把手教你实现管道 - 过滤器架构

(一)定义过滤器接口

public interface Filter<T> {//对输入数据进行处理并返回处理结果T process(T input);
}

这里定义了一个泛型接口Filter,它只有一个方法process,用于对输入数据进行处理并返回处理结果。

(二)实现具体过滤器

以一个简单的文本处理为例,我们实现两个过滤器:“文本大写转换过滤器” 和 “文本添加前缀过滤器”。

// 文本大写转换过滤器
public class UppercaseFilter implements Filter<String> {@Overridepublic String process(String input) {return input.toUpperCase();}
}// 文本添加前缀过滤器
public class PrefixFilter implements Filter<String> {@Overridepublic String process(String input) {return "处理后: " + input;}
}

(三)实现管道类

import java.util.ArrayList;
import java.util.List;public class Pipeline<T> {private final List<Filter<T>> filters = new ArrayList<>();//向管道中添加过滤器public Pipeline<T> addFilter(Filter<T> filter) {this.filters.add(filter);return this;}//按照顺序依次调用每个过滤器的process方法,对输入数据进行处理public T execute(T input) {T output = input;for (Filter<T> filter : filters) {output = filter.process(output);}return output;}
}

Pipeline类中,我们使用一个List来存储过滤器。addFilter方法用于向管道中添加过滤器,execute方法则按照顺序依次调用每个过滤器的process方法,对输入数据进行处理。

(四)使用示例

public class Main {public static void main(String[] args) {Pipeline<String> pipeline = new Pipeline<>();pipeline.addFilter(new UppercaseFilter()).addFilter(new PrefixFilter());String input = "hello world";String result = pipeline.execute(input);System.out.println(result);}
}

main方法中,我们创建了一个Pipeline对象,并向其中添加了两个过滤器。然后输入一段文本 “hello world”,经过管道处理后,最终输出 “处理后: HELLO WORLD”。

四、管道 - 过滤器架构的优势与适用场景

(一)核心优势

高内聚低耦合:每个过滤器独立完成自己的任务,与其他过滤器之间的耦合度极低。例如在电商系统的订单处理中,“库存检查过滤器” 和 “支付处理过滤器” 可以独立开发和维护,一个过滤器的修改不会影响到另一个。

可扩展性强:当业务需求发生变化,需要增加新的数据处理逻辑时,只需新增一个过滤器并将其添加到管道中即可,无需对整个系统进行大规模改动。

支持并行处理:多个过滤器可以并行运行,提高数据处理效率。比如在图像处理系统中,“图像缩放过滤器” 和 “图像色彩调整过滤器” 可以同时对图像进行处理。

(二)适用场景

数据处理系统:如 ETL(Extract - Transform - Load)工具,用于从不同数据源提取数据,进行转换后加载到数据仓库中。

编译器:编译器的各个阶段(词法分析、语法分析、语义分析等)可以看作是过滤器,通过管道依次处理源代码。

Web 应用中间件:在 Web 应用中,请求处理过程可以使用管道 - 过滤器架构,例如通过过滤器实现请求日志记录、身份认证、参数校验等功能。

五、使用管道 - 过滤器架构的注意事项

虽然管道 - 过滤器架构有诸多优势,但也并非适用于所有场景。在使用时需要注意:

数据格式一致性:各个过滤器之间的数据格式需要保持一致,否则在管道传输过程中可能会出现问题。这就要求在设计过滤器时,明确输入和输出的数据格式标准。

性能开销:如果管道中过滤器数量过多,数据在管道中的传输和处理可能会带来一定的性能开销。因此需要合理规划过滤器的数量和处理逻辑,避免性能瓶颈。

错误处理:由于过滤器之间相互独立,当某个过滤器出现错误时,需要有完善的错误处理机制,确保不会影响整个系统的稳定性。

总结

管道 - 过滤器架构它就像一把 “瑞士军刀”,在数据处理领域有着广泛的应用和强大的能力。无论是在实际项目中,还是在技术学习过程中,掌握这种架构风格都能为我们带来更多的思路和解决方案。


图片来源网络

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

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

相关文章

【VIM】vim 常用命令

文章目录 插入模式光标移动拷贝/粘贴/删除/撤销块操作分屏代码缩进命令组合使用其他PowerVim 前言&#xff1a;本文内容大部分摘抄自酷壳和博客园   –   CoolShell – 陈皓   博客园 – 易先讯 插入模式 a → 在光标后插入o → 在当前行后插入一个新行O → 在当前行前插…

polarctf-web-[简单rce]

考点&#xff1a; (1)RCE(eval函数) (2)执行函数(passthru函数) (3)/顶级(根)目录查看 (4)sort排序查看函数 题目来源&#xff1a;Polarctf-web-[简单rce] 解题&#xff1a; 代码审计 <?php/*​PolarD&N CTF​*/highlight_file(__FILE__);function no($txt){ # …

HarmonyOs开发之———使用HTTP访问网络资源

谢谢关注&#xff01;&#xff01; 前言&#xff1a;上一篇文章主要介绍HarmonyOs开发之———Video组件的使用:HarmonyOs开发之———Video组件的使用_华为 video标签查看-CSDN博客 HarmonyOS 网络开发入门&#xff1a;使用 HTTP 访问网络资源 HarmonyOS 作为新一代智能终端…

Vue 图片预览功能(含缩略图)

众所周知&#xff0c;常见的组件库如Element、Ant Design&#xff0c;自带的图片预览功能都没有缩略图&#xff0c;所以 需要单独封装一个图片预览的服务。 第三方库&#xff1a;v-viewer 安装&#xff1a; npm install v-viewer viewerjs 若使用报错&#xff0c;可安装指定…

手写tomcat:基本功能实现(4)

逻辑架构 HTTP 请求与 Socket&#xff1a; 左侧的 “HTTP 请求” 箭头指向 “socket”&#xff0c;表示客户端发送的 HTTP 请求通过 socket 传输到服务器。Socket 负责接收请求&#xff0c;并提取出其中的 请求路径&#xff08;如 /first&#xff09;和 请求方法&#xff08;如…

jvm安全点(一)openjdk17 c++源码垃圾回收安全点信号函数处理线程阻塞

1. 信号处理入口​​ ​​JVM_HANDLE_XXX_SIGNAL​​ 是 JVM 处理信号的统一入口&#xff0c;负责处理 SIGSEGV、SIGBUS 等信号。​​javaSignalHandler​​ 是实际注册到操作系统的信号处理函数&#xff0c;直接调用 JVM_HANDLE_XXX_SIGNAL。 ​​2. 安全点轮询页的识别​​ …

微信小程序:封装表格组件并引用

一、效果 封装表格组件,在父页面中展示表格组件并显示数据 二、表格组件 1、创建页面 创建一个components文件夹,专门用于存储组件的文件夹 创建Table表格组件 2、视图层 (1)表头数据 这里会从父组件中传递表头数据,这里为columns,后续会讲解数据由来 循环表头数组,…

【FMC216】基于 VITA57.1 的 2 路 TLK2711 发送、2 路 TLK2711 接收 FMC 子卡模块

产品概述 FMC216 是一款基于 VITA57.1 标准规范的 2 路 TLK2711 接收、2 路 TLK2711 发送 FMC 子卡模块。该板卡支持 2 路 TLK2711 数据的收发&#xff0c;支持线速率 1.6Gbps&#xff0c;经过 TLK2711 高速串行收发器&#xff0c;可以将 1.6Gbps 的高速串行数据解串为 16 位并…

K8S Gateway API 快速开始、胎教级教程

假设有如下三个节点的 K8S 集群&#xff1a; ​​ k8s31master 是控制节点 k8s31node1、k8s31node2 是工作节点 容器运行时是 containerd 一、Gateway 是什么 背景和目的 入口&#xff08;Ingress&#xff09;目前已停止更新。新的功能正在集成至网关 API 中。在 Kubernetes …

时序数据库IoTDB分布式架构解析与运维指南

一、IoTDB分布式架构概述 分布式系统由一组独立的计算机组成&#xff0c;通过网络通信&#xff0c;对外表现为一个统一的整体。IoTDB的原生分布式架构将服务分为两个核心部分&#xff1a; ‌ConfigNode&#xff08;CN&#xff09;‌&#xff1a;管理节点&#xff0c;负责管理…

Ubuntu 20.04 LTS 中部署 网页 + Node.js 应用 + Nginx 跨域配置 的详细步骤

Ubuntu 20.04 LTS 中部署 网页 Node.js 应用 Nginx 跨域配置 的详细步骤 一、准备工作1、连接服务器2、更新系统 二、安装 Node.js 环境1、安装 Node.js 官方 PPA&#xff08;用于获取最新稳定版&#xff09;&#xff1a;2、安装 Node.js 和 npm&#xff08;LTS 长期支持版本…

3DVR制作的工具或平台

3DVR&#xff08;三维虚拟现实&#xff09;是利用三维图像技术和虚拟现实技术&#xff0c;将真实场景进行三维扫描并转换成计算机可识别的三维模型&#xff0c;使用户能够在虚拟空间中自由漫游&#xff0c;体验身临其境的感觉。3DVR技术结合了全景拍摄和虚拟现实&#xff0c;提…

垂直智能体:企业AI落地的正确打开方式

在当前AI浪潮中&#xff0c;许多企业急于跟进&#xff0c;推出自己的AI智能体解决方案。然而&#xff0c;市场上大量出现的"万能型"智能体却鲜有真正解决实际问题的产品。本文将探讨为何企业应该专注于开发垂直领域智能体&#xff0c;而非追求表面上的全能&#xff0…

软件工程各种图总结

目录 1.数据流图 2.N-S盒图 3.程序流程图 4.UML图 UML用例图 UML状态图 UML时序图 5.E-R图 首先要先了解整个软件生命周期&#xff1a; 通常包含以下五个阶段&#xff1a;需求分析-》设计-》编码 -》测试-》运行和维护。 软件工程中应用到的图全部有&#xff1a;系统…

王者荣耀游戏测试场景题

如何测试一个新英雄&#xff1a;方法论与实践维度 测试一个新英雄不仅仅是“打打打”&#xff0c;而是一套完整的测试流程&#xff0c;包括设计文档验证、功能验证、数值验证、性能验证、交互验证等。可以从以下多个角度展开&#xff1a; &#x1f50d; 1. 方法论维度 ✅ 测试…

第四天的尝试

目录 一、每日一言 二、练习题 三、效果展示 四、下次题目 五、总结 一、每日一言 很抱歉的说一下&#xff0c;我昨天看白色巨塔电视剧&#xff0c;看的入迷了&#xff0c;同时也看出一些道理&#xff0c;学到东西&#xff1b; 但是把昨天的写事情给忘记了&#xff0c;今天…

多模态大语言模型arxiv论文略读(七十八)

AID: Adapting Image2Video Diffusion Models for Instruction-guided Video Prediction ➡️ 论文标题&#xff1a;AID: Adapting Image2Video Diffusion Models for Instruction-guided Video Prediction ➡️ 论文作者&#xff1a;Zhen Xing, Qi Dai, Zejia Weng, Zuxuan W…

优化 Spring Boot 应用启动性能的实践指南

1. 引言 Spring Boot 以其“开箱即用”的特性深受开发者喜爱,但随着项目复杂度的增加,应用的启动时间也可能会变得较长。对于云原生、Serverless 等场景而言,快速启动是一个非常关键的指标。 2. 分析启动过程 2.1 启动阶段概述 Spring Boot 的启动流程主要包括以下几个阶…

Ubuntu下配置VScode出现#include错误请更新includePath的解决方法

首先Ubuntu新手小白一定要先安装g&#xff0c;安装方法是&#xff1a; 在桌面右键打开终端&#xff0c;输入&#xff1a;sudo apt-get install g 安装好g之后&#xff0c;在vscode终端输入&#xff1a;g -v -E -x c - 输出这些路径&#xff0c;复制 如果还存在显示cout不存在的…

【背包dp】小结

背包问题总结 一、什么是背包问题&#xff1f; 定义&#xff1a;给定一个容量为 W 的背包和 n 件物品&#xff0c;每件物品有一个重量 w[i] 和价值 v[i]&#xff0c;要求选择若干物品放入背包&#xff0c;在不超过容量的前提下&#xff0c;使总价值最大。 背包问题本质是&am…