管道和过滤器
管道和过滤器是八种体系结构模式之一,这八种体系结构模式是:层、管道和过滤器、黑板、代理者、模型-视图-控制器(MVC) 表示-抽象-控制(PAC)、微核、映像。
管道和过滤器适用于需要渐增式处理数据流的领域,而常见的“层”模式它 能够被分解成子任务组,其中每个子任务组处于一个特定的抽象层次上。
按照《POSA(面向模式的软件架构)》里的说法,管道过滤器(Pipe-And-Filter)应该属于架构模式,因为它通常决定了一个系统的基本架构。管道过滤器和生产流水线类似,在生产流水线上,原材料在流水线上经一道一道的工序,最后形成某种有用的产品。在管道过滤器中,数据经过一个一个的过滤器,最后得到需要的数据。
管道&过滤器模型的基本部件都有一套输入输出接口。每个部件从输入接口中读取数据,经过处理,将结果数据置于输出接口中,这样的部件称为“过滤器”。这种模型的连接者将一个过滤器的输出传送到另一个过滤器的输入,
我们把这种连接者称为“管道”。在这种模型中,过滤器必须是独立的实体,每一个过滤器的状态不受其它过滤器的影响,并且,虽然人们对过滤器的输入输出有一定的规定,但过滤器并不需要知道向它提供数据流的过滤器和
它要提供数据流的过滤器的内部细节。任何两个过滤器,只要它们之间传送的数据遵守共同的规约就可以相连接。
每个过滤器都有自己独立的输入输出接口,如果过滤器间传输的数据遵守其规约,只要用管道将它们连接就可以正常工作。
查询的关注点
基于以上管道和过滤器特点,它为处理数据流的系统提供了一种良好的结构,每一个处理步骤封装在一个过滤器组件中,数据通过相邻的过滤器之间的管道传输。在程序处理中,也有类似的这种数据流,最常见的就是命令处理的数据流,它从最开始的查询命令,到最后的结果输出,会经过多个步骤,以ADO.NET来说,执行一个查询会经过以下过程:
查询命令:
- 获取数据集:
-
- 打开数据库连接 IDbConnection
- 创建命令对象 IDbCommand
- 创建数据适配器 IDataAdapter
- 填充数据集 IDataAdapter.Fill(DataSet)
- 关闭数据库连接
- 返回数据集 DataSet
- 获取数据阅读器
-
- 打开数据库连接 IDbConnection
- 创建命令对象 IDbCommand
- 执行数据阅读器查询 IDbCommand.ExecuteReader
- 返回数据阅读器 IDataReader
- 关闭数据库连接
非查询命令:
- 打开数据库连接 IDbConnection
- 创建命令对象 IDbCommand
- 执行查询 IDbCommand.ExecuteNonQuery()
- 关闭数据库连接
可以看到,上面这几种查询命令的执行,都要经过几个相同的步骤:打开数据库连接,创建命令对象,执行查询,返回结果,关闭数据库连接,这几个步骤是有严格顺序的,前后依赖的,就像水流一般,因此,我们也可以利用“管道--过滤器”模式,在查询命令的执行过程中,插入某些特定的处理逻辑。
从最终使用者的角度来说,一个查询有4个关注点:
- 查询前
- 查询中
- 查询后
- 查询异常
其中,查询中是ADO.NET等数据访问组件内部的处理过程,一般不能直接提供用户可以切入和干预的观察点,那么剩下3个关注点,就是我们可以用的,这3个关注点,就像一个水管的三个阀门一样。
SOD框架的命令处理管道
命令处理接口
SOD框架现在也提供了这样的三个关注点,使得使用组件的用户,能够无需修改组件内部的代码,改变和观察组件的处理情况,这三个关注点对应的是 ICommandHandle接口的3个方法:
/// <summary> /// 查询命令处理器接口 /// </summary> public interface ICommandHandle { /// <summary> /// 获取当前适用的数据库类型,如果通用,请设置为 UNKNOWN /// </summary> DBMSType ApplayDBMSType { get; } /// <summary> /// 执行前处理,比如预处理SQL,补充设定参数类型,返回是否继续进行查询执行