POSA 本でアーキテクチャパターンを勉強しよう(2) - アーキテクチャパターン「混沌から構造へ」より「Layers(レイヤパターン)」
- パターンとは何か?
- アーキテクチャパターン「混沌から構造へ」より「Layers(レイヤパターン)」
- アーキテクチャパターン「混沌から構造へ」より「Pipes and Filters」
- アーキテクチャパターン「混沌から構造へ」より「Blackboard」
解決策
レイヤの名前の通り、システムを複数のレイヤで階層化することで、分割が必要な大規模システムに対処します。POSA 本によると、この解決策の本質は、一つのレイヤに同じレベルの抽象度の要素をまとめて処理を行うことができるというものです。
それでは、このパターンの静的側面(静的構造)と動的側面を紹介していくことにします。
静的側面
レイヤパターンは、システムを複数のレイヤで分割し、各レイヤは隣接するレイヤとしか相互作用を持ちません。下図では、あるレイヤが一つ下のレイヤに依存していることを表現しています。あるレイヤの責務は、一つ上のレイヤによって私用されるサービスを提供し、一つ下のレイヤに処理を委譲するということができます。
レイヤの静的側面(by Kodougu)
通常、レイヤパターンは隣接しないレイヤへのアクセスを禁止します。ただ、前述のプレゼンテーションレイヤが直接ドメインレイヤを呼び出すとうまくいくようなケースでは、レイヤのルールを厳密に適用すると開発コストが高くなる可能性があります。
動的側面
POSA では、動的側面の 5 つのシナリオを紹介しています。
一つめのシナリオは、クライアントが最上位のレイヤにリクエストを出し、レイヤが一つ下のレイヤにそのリクエストを伝え、一つ下のレイヤがさらに一つのレイヤに伝えるというようなケースです、ウェブアプリケーションならユーザによる入力から最下層のデータベースまでの流れになるでしょう。このようなケースをトップダウン通信と呼ぶそうです。
二つ目のシナリオは、この逆です。最下層レイヤへの入力を受けて上位層にその入力を通知していくというものです。下位レイヤが上位レイヤに依存しないように、オブザーバパターンのような仕組みを採用する場合があります。このようなケースをボトムアップ通信と呼ぶそうです。
三つ目のシナリオは、一つめのシナリオの限定ケースです。最上位で受けたリクエストを最下層のレイヤにまで伝えず途中で処理を終わらせる場合です。クライアントサーバで、クライアント側の下位の層がキャッシュとなってサーバにアクセスしないような場合が考えられます。
四つ目のシナリオは、二つ目のシナリオの限定ケースです。最下層レイヤへの入力を受けて上位層にその入力を通知する際に途中のレイヤで止めてしまうというものです。POSA 本では、通信の例を挙げていて、気の短いクライアントから少し前に送信されたリクエストを再送信する場合に、最初のリクエストに対するレスポンスと再送信されたリクエストが交差する場合があります。このような場合は、再送信されたリクエストを上位レイヤに伝えずに下位レイヤで把握して、それ以上のアクションを起こさないようにするということをするようです。
五つ目のシナリオは、二つのレイヤスタックを持つ場合です。クライアントが片方のレイヤスタックの最上位に入力を行い、最下層まで達したら通信してもう一つのレイヤスタックの最下層にリクエストを送り、最下層のレイヤは上位のレイヤに伝えていくというような動作です。
五つ目のシナリオ(by Kodougu)
レイヤパターンはおよそこのような動的側面を持っています。
実現手段
POSA 本で紹介されている方法について簡単に触れましょう。まずはレイヤをを見つける作業を行います。(1) タスクやオブジェクトを列挙してグループ化する、(2) (1) の結果から抽象レベルの数(レイヤの深さ)を決定する、(3) レイヤに名前を名前をつけてタスクやオブジェクトを割り振る、(4) レイヤが提供するサービスを仕様化する、(5) (1) ~ (4) を繰り返してレイヤを洗練するという流れになります。
次に、個別のレイヤを設計していきます。(6) 各レイヤのインタフェースを決定する、(7) ここのレイヤを構造化する、(8) 隣接するレイヤ間の相互作用を仕様化する、(9) 隣接するレイヤの結合を解除する、(10) 例外処理戦略を設計するという流れになります。
このような流れでレイヤを設計していきます。ただ、こうしたトップダウンの手法が必ずしもとられるとは限らず、前述の3層構造のようにあらかじめ用意されているレイヤパターンを採用したり、既存のシステムや製品のロックインなど、ボトムアップに決まる場合もあります。
プレゼンテーションモデルと Ruby on Rails
ビジネスロジックを実行する際に使われるクラス(ドメインモデル)と、画面上に表示する情報は必ずしも一致しません。そこで、画面上の情報と一致しやすいクラス(プレゼンテーションモデル)をサービスレイヤで構築します。
Ruby on Rails はバージョン 1 の頃はそれほどこのようなドメインモデルとプレゼンテーションモデルのギャップを意識していませんでした。データベーススキーマから画面までギャップがないシステムが前提になっており、それほど複雑なシステムを対象にしていなかったのです。
バージョン 2 では、RESTful な API を効率的に実装する拡張が行われました。Flash, Ajax, Windows アプリなどのリッチなクライアントに対してシンプルな API を提供するためのフレームワークという性格が強くなってきました。
前述の3層構造で言うと、プレゼンテーションレイヤをそうしたリッチなクライアントに任せるために、サービスレイヤとドメインレイヤを Rails が対象とするという感じです。Rails の MVC における M(Model)はドメインレイヤ、VC(View-Controller)は、サービスレイヤです。プレゼンテーション層が効率的に利用するためのプレゼンテーションモデルを生成する役割をサービスレイヤが担うというわけです。
この種の議論は Java の世界になりますが、Seasar2 のコミュニティが進んでいるという印象を持っています。
このサイトについて
TrackBack URL :
