管道和过滤器

现在的学习笔记要侧重自己的理解。用自己的语言,经验来阐释它。读一段后,写下我的理解。

管道和过滤器体系结构模式为数据流的系统提供了一种结构。每个处理步骤封装在一个过滤器组件中,过滤器组件间通过通道连接。重组管理器组件可以得到不同的系统族。这个和之前见过的一个语音流的处理结构非常相似。

1. 例子

这里列举了一个编译器软件。从代码到可执行文件经过了很多步骤,每个步骤都抽象成一个过滤器组件。

和处理数据流的例子很像。比如一个数据流,从接收到用扬声器播放,会经过很多的编解码步骤。每个步骤其实也是过滤器。

2. 语境

处理数据流。

3. 问题

  1. 保持系统的灵活性。可以通过替换处理步骤,或对处理步骤进行排序来进行系统升级。
  2. 把这个系统划分为一个个小的组件,这些组比大粒度组件更易于重用。
  3. 不相连接的处理步骤不共享信息???相互了解的步骤需要共享信息吗?不需要。只要输出指定格式的数据流即可。
  4. 后面两个难于理解。

这样的系统有一个特点,不需要人的参与,和人的交互性补强。比如一个交互式的事件驱动的系统则不宜使用此模式。

4. 解决方案

把整个系统分解成几个序贯的步骤。每个步骤有一个过滤器组件实现。这些步骤通过管道连接,数据流在管道中流动。一个步骤的输入是上一个步骤的输出,而它的输出则是下一个步骤的输入。

第一个过滤器的输出成为数据源,最后一个过滤器的输出成为数据汇点。

简单的解决方案是线性的:

clip_image002

复杂一点的,可能存在数据汇接点:

clip_image004

5. 结构

过滤器是流水线(其实相当于整个系统,流水线只是形象的说法)的处理单元。

过滤器可以分为主动过滤器和被动过滤器,区分的标准是他们处理数据的方式,是主动获取输入并且输出,还是等待输入,并且等待输出。

管道表示过滤器之间的连接。有一种方案,就是主动过滤器调用被动过滤器,比如前一个过滤器处理完毕数据流后,直接调用后一个过滤器来处理数据流,这样管道就是过滤器组件间的调用。这样有个问题,会降低系统的灵活性。可以考虑建立一个专门的过滤器类来完成类似工作。后面对系统的重组其实就是对管道的重组或重定义。

6. 动态特性

  1. 一个推进流水线,过滤器活动通过向被动过滤器写数据而启动。也就是可以理解为输入时被动的,而输出时主动的。
  2. 一个拉的流水线,也就是可以理解为输入时主动的,输出时被动的。
  3. 混合了推和拉。
  4. 所有的过滤器都循环的主动拉出、计算并推入数据。这个方案有一个好处,就是每个过滤器都可以是一个单独的进程或线程。对于处理大量的数据是有好处的。
  5. 所有的过滤器都是被动的,而所有的操作都由管道来触发,它循环的从过滤器拉数据并且向过滤器推入数据。
  6. 过滤器之间全部用通道连接,所有的过滤器都是被动输入,主动输出。这样就减少了缓冲处理步骤。另外,这个在实现上可以将这个系统作为一个程序,而每个过滤器只是程序的一个模块。这个方案的复杂度相对较低,适合小型系统构建。这其实是第一种方案。

7. 实现

  1. 本系统划分为一系列的处理阶段。每一个处理阶段必须只依赖前一阶段的输出。
  2. 定义沿每个管道传输的数据格式。
  3. 决定如何实现每个管道连接。
  4. 设计和实现过滤器。
  5. 设计错误处理。这是一个难点。需要根据具体的应用来做权衡。
  6. 建立处理流水线。

8. 效果

优点:灵活性,可以通过重组过滤器来实现不同的处理过程;可以方便的替换过滤器;过滤器组件可以重用;并行处理提高效率;

缺点:不易于共享全局状态;数据转换的额外开销;错误处理;

原文地址:https://www.cnblogs.com/chgaowei/p/2060215.html