読者です 読者をやめる 読者になる 読者になる

【アーキテクチャパターン】POSA Vol.1のPipes and Filters(パイプ&フィルタ)

Pattern-Oriented Software Architecture Vol.1に載っているアーキテクチャパターンの1つ,Pipes and Filtersをまとめる.

Pipes and Filtersアーキテクチャパターンは,データをストリームとして扱うシステムのための構造を提供する. 個々の処理ステップは,1つのフィルタコンポーネントにカプセル化され,データはこれらの隣接するフィルタ間をパイプコンポーネントを介して引き渡される. フィルタの組み合わせを換えることにより,機能の類似した一連のシステムを作成することができる.

前提

データストリームの処理

課題

入力データストリームの処理をするシステムの構築の際,下記の理由から一つのコンポーネントで実装するのではなく,「システムの処理ステップを交換したり並べ替えたりできる」柔軟性を持たせる必要がある.

  • 複数の開発者でシステムを開発を行う
  • 自然と複数の処理ステップに分割できる
  • システムへの要件は変更しやすい

このような柔軟性のあるシステムの設計では,下記のフォースを考察しなければならない.

  • 処理ステップの交換やその組み合わせ変更により,将来のシステム拡張が可能
  • 1つの処理ステップが小さい
  • 非隣接処理ステップは,情報を共有しない
  • 入力データの発生源が複数存在する
  • さまざまな方法で,最終結果を表示・保存できる
  • 今後の処理のために中韓結果をファイルに明示的に格納すると煩雑になり,誤りが生じやすい.
  • ステップの多重処理を除外することはできない

解決策

システムタスクを複数のシーケンシャルな処理ステップに分割する. このステップは,システムのデータフローによって接続される. すなわち,ステップの出力データは,後続ステップの入力となる.

  • 各処理ステップを実装したコンポーネントをフィルタと呼ぶ.
  • システムへの入力は,テキストファイルなどのデータソースから提供される.
  • 出力は,ファイル,端末,アニメーションプログラムなどのデータシンクに流れる.
  • データソース,フィルタ,データシンクは,パイプによりシーケンシャルに接続される.
    それぞれのパイプが隣接処理ステップ間のデータフローを実装する.
    パイプによって結び付けられたフィルタのシーケンスは,処理のパイプラインと呼ばれる.

静的側面

フィルタ(Fileter)

パイプラインの処理単位. 下記の3つの基本的な原理を組み合わせてフィルタの実装を行う.

  • 計算,情報追加などにより価値を高める
  • 情報を集中させたり,除去したりして,洗練を加える
  • 他の表現形式に変換を施す

フィルタのアクティビティが開始するのは下記のようなイベントによる. * 受動フィルタ * パイプライン要素のサブシーケンスが,フィルタからの出力を引き出す(プル) * その前に存在するパイプライン要素が,新しい入力データをフィルタに送り出す(プッシュ) * 能動フィルタ * ループ内でフィルタが活性化される.ループがパイプラインから入力データを引き込み,そのパイプラインへ出力データを送り出す.

パイプ(Pipe)

フィルタ間およびデータソースと最初のフィルタ間,最後のフィルタとデータシンク間の接続を表す.

データソース(Data Source)

システムへの入力を表現したもの. 同一構造や同一型のデータ値からなるシーケンスを提供する.

データシンク(Data Sink)

パイプラインの終端から結果を集める.

動的側面

最初の3つは受動フィルタ. 最後が最も一般的なシナリオ.

シナリオ1

データソースからアクティビティが開始される. プッシュパイプライン フィルタのアクティビティは,受動フィルタへのデータ書き込みによって駆動される. f:id:yusuke_ujitoko:20161116213136p:plain

シナリオ2

プルパイプライン. データを呼び出すデータシンクによって,制御フローが開始される. f:id:yusuke_ujitoko:20161116213147p:plain

シナリオ3

プッシュパイプラインとプルパイプラインが混在している受動データソースと受動データシンクが存在し,2番目のフィルタが能動的に働き,処理を開始させる. f:id:yusuke_ujitoko:20161116213234p:plain

シナリオ4

Pipes and Filtersの典型例.すべてのフィルタが能動的にデータを引き込み,計算を行いそれをプッシュする. 各フィルタは,独立プロセスなどの独自の制御スレッドで稼働している. フィルタ間のパイプがバッファ機能をもち,フィルタの動機を行う. f:id:yusuke_ujitoko:20161116213410p:plain

実装

  1. システムタスクを処理段階に分ける
    • この時点で,処理段階の代替物や別の組み合わせを考慮する
  2. それぞれのパイプに引き渡されるデータフォーマットを定義する
    • 統一フォーマットが定義できると,フィルタの組み合わせを自由に行えるので柔軟性が向上する
    • ただし効率の低下を招くおそれがある.
  3. 各パイプ接続の実装方法を決定する.
    • もっとも単純なパイプ接続は,プルorプッシュで直接呼び出しを行うことだが,その場合組み合わせ変更には,コードの変更が必要となる.
  4. フィルタを設計し,実装する
    • 受動フィルタ
      • データプル型は関数
      • データプッシュ型は手続き
    • 能動フィルタはプロセスやスレッド
  5. 例外処理を設計する
  6. 処理のパイプラインを設定する

バリエーション

teeとジョインパイプラインシステム(Tee and join pipeline systems)

Pipes and Filtersパターンの単一入力・単一出力のフィルタしようというのを変化させて,1つ以上の入力を持つフィルタ,1つ以上の出力を持つフィルタなどを差k末井できる. その時処理はフィードバックループも可能な有向グラフとして設定される.

適用例

UNIX

コマンドシェルと数多くのフィルタプログラム.

CMSパイプライン

IBMメインフレームのOSを拡張して,Pipes and Filtersのアーキテクチャを支援するようにしたもの.

LASSTools

数値解析とそのグラフィックスを支援するツールセット.

結論

Pipes and Filtersの利点

  • 中間ファイルが利用できるが必須ではない.
  • フィルタ交換の柔軟性
  • 組み合わせ変更による柔軟性
  • フィルタコンポーネントの再利用性
  • パイプラインのラピッドプロトタイピング
  • 並列処理による効率性

Pipes and Filtersの欠点

  • 状態情報の共有が高価である,あるいは柔軟ではない
  • 並列処理の効果が期待できないことがしばしばある
  • データ変換のオーバーヘッド
  • 例外処理

yusuke-ujitoko.hatenablog.com