架构模式Pipes and Filters提供的结构适合用于处理数据流的系统。每个处理步骤封装在一个过滤器组件中,数据通过相邻过滤器之间的管道传输。通过重组过滤器,可打造多个相关的系统组。
背景
处理数据流
问题
假设要打造的系统必须对输入数据进行处理或转换,以单个组件的方式实现这种系统可能不可行,原因有多个:系统必须由多名开发人员打造;整个系统要完成的任务分多个处理阶段;需求很可能发生变化。
因此,需要提供灵活性,以便能够更换处理步骤或调整处理顺序。提供这样的灵活性后,便可使用既有处理组件打造出一些列系统。设计系统时,必须考虑如下作用力。
- 以后可通过更换或重组处理步骤来改进系统。
- 相比大型组件,在其他环境中重用小型处理步骤更容易。
- 不相邻的处理步骤不共享消息。
- 存在不同的输入数据源,如网络连接和提供温度的硬件传感器。
- 最终结果能够以各种方式和存储。
- 如果要求用户将中间结果存储到文件中,供以后进一步处理,将很容易出错。
- 应避免同时执行多个处理步骤,如并行或半并行地执行这些步骤。
解决方案
架构模式Pipes and Filters将系统面临的任务分为多个一次执行的处理步骤。这些步骤通过在系统中传输的数据相关联:一个步骤的输出是下一个步骤的输入。每个处理步骤都由过滤器组件实现。过滤器一边使用数据一边提供数据,而不是等到获得所有输入后才生成输出。这降低了延迟,实现了真正的并行处理。数据源、过滤器、数据接收器通过管道依次相连,每条管道都在相邻处理步骤之间传输数据。
结构
过滤器组件式流水线的处理单元,负责充实、提炼或转换输入数据。
过滤器操作可由多种事件触发:
- 下一个流水线元素从过滤器拉去输出。(被动过滤器)
- 前一个流水线元素向过滤器推送输入。(被动过滤器)
- 过滤器不间断地循环,从流水线上游拉去输入,并向下游推送输出。(主动过滤器)
管道指的是过滤器之间、数据源和第一个过滤器之间以及最后一个过滤器和数据接收器之间的连接。将两个主动过滤器组件相连时,管道负责让它们同步,这是使用先进先出缓冲区实现的。被动过滤器与主动过滤器相连时,可这样实现管道:由主动过滤器直接调用被动过滤器,但直接调用增加了重组过滤器的难度。
数据源指的是系统输入,提供结构或类型相同的数据序列,如包含文本行的文件或提供数字序列的传感器。
数据接收器从流水线末端收集结果,分主动接收器和被动数据接收器。
实现
Pipes and Filters架构实现起来很简单。可将系统服务(如消息队列或UNIX管道)用作管道连接,也可采取其他方式,如直接调用。
- 将系统要完成的任务划分为一系列处理阶段。
- 定义沿管道传递的数据的格式。
- 确定如何实现每条管道连接。
- 设计并实现过滤器。
- 实际错误处理机制。UNIX为错误消息定义了专用输出通道stderr。过滤器并行运行时,单个错误通道可能包含来自不同组件的错误消息,这即不明显又无法预测。
- 搭建处理流水线。
效果
优点:
1. 不需要中间文件,但也可以使用。
2. 可更换过滤器。
3. 可重组过滤器
4. 可重用过滤器组件
5. 可快速创建流水线原型。
6. 效率因并行处理得以提高。
缺点:
1. 共享状态信息的开销高昂或缺乏灵活性。
2. 通过并行处理提高效率的初衷常常成为泡影。
3. 数据转换开销。
4. 错误处理。