Patterns of Enterprise Application Architecture, Chapter 1 Layering を参考にレイヤ化アーキテクチャとはどういったものなのかをまとめました
レイヤ化は、複雑なソフトウェアのシステムを分割するために使用される技法です。コンピュータの構造やネットワークなどソフトウェア以外の設計でも使われています。各レイヤはその下のレイヤに依存します。レイヤ3はレイヤ2を利用して、レイヤ2はレイヤ1を利用します。レイヤ化アーキテクチャにおいて最も難しいのは、必要なレイヤと各レイヤが行うべき内容を決定することです。
レイヤ化のメリット
- 他のレイヤを気にせず、1つのレイヤを全体として考えることができる
- 同じインターフェースを持つだいたい実装でレイヤを置き換えることができる
- レイヤ間の依存を最小限にできる
- レイヤは標準化に適している
- レイヤを構築することにより、多くの高水準サービスがそのレイヤを使用できるようになる
レイヤ化のデメリット
- 物事をカプセル化してしまうため、連鎖的な変更が起こる場合がある
- パフォーマンスを損ねる場合がある
UI上で表示すべきフィールドの追加が、前者の具体的な例になります。追加されるフィールドに対応するものがデータベース上に存在する必要があります。このためUIからデータベースまでのすべてのレイヤにそのフィールドを追加する必要が生じます。後者についてはパフォーマンス損失以上にトランザクションの制御などの最適化によって得られる恩恵が多いケースもあるので検討が必要です。
レイヤ化の発展
90年代に登場したクライアント/サーバシステムは2レイヤのシステムでした。クライアントはUIとアプリケーションコードを保持して、サーバーは通常のRDBという構成でした。アプリケーションがRDBの内容の表示と更新といった単純なものであれば適切に動作しましたが、妥当性の検証など複雑なドメインロジックを伴い始めると、たちまち重複コードが増えたり、コードの扱いが難しくなったりする局面がでてきました。そのころオブジェクト指向も注目を集めていて、コミュニティではプレゼンテーション、ドメインロジック、データソースの3レイヤにすることにより、ドメインロジックに関する問題を解決しました。最終的にはWebやJavaの登場により、こうしたやり方が受け入れられ、定着することとなりました。
3層レイヤ
プレゼンテーションレイヤ
ユーザとソフトウェアの相互作用を扱うのがこのレイヤの役割になります。ユーザーに情報を表示したり、ユーザーからのコマンドをドメインやデータソースでの動作に変換したりするようなコードがここに含まれます。
ドメインレイヤ
システムそのものであるロジックを置くレイヤです。ビジネスロジックとも呼ばれます。入力データや格納データに基づく計算や、入力データの妥当性検証、また状況に応じたデータソースの選択などがこのレイヤに含まれます。
データソースレイヤ
他のシステムとの通信を行い、アプリケーションのためにタスクを実行します。
レイヤ化アーキテクチャとヘキサゴナルアーキテクチャ
ヘキサゴナルアーキテクチャは、外部システムへのインターフェースで囲まれた核としてシステムを視覚化したものです。外部にあるものはすべて外側のインターフェースとします。よって、ヘキサゴナルアーキテクチャは他への提供するサービスと他のサービスを利用することを区別しない、対称的な構造を持っています。対して、レイヤ化アーキテクチャは、他へのサービスとして提供するインターフェースと、他のサービスを利用することを区別する、非対称的なスキーマになっています。そして、この部分がプレゼンテーションレイヤとデータソースレイヤの違いとなっています。
レイヤリングの方法
システムの規模によって異なります。単純なものであれば、各レイヤのふるまいをサブルーチンとしてあげるだけで大丈夫です。より複雑なときにはクラスに分割を行い、さらに複雑な場合には幾つかのパッケージにクラスを分割してあげるということができます。状況によって一番適切な分割をするのが望ましいですが、最低でもサブルーチンレベルでの分割を行う必要はありそうです。
レイヤ間の依存関係
ドメインとデータソースはプレゼンテーションに依存しないようにします。ドメインとデータソースの関係は複雑なため、データソースのアーキテクチャに応じて考えていく必要がありそうです。
レイヤの実行
PoEAAの内容のかなりの部分は、論理的なレイヤについて解説したものになっています。システムを分割して、その境界部の結合を減らすことについての説明が書かれています。レイヤの分割は1台の物理マシンで実行していたとしても役に立ちます。しかし実行場所が異なることによって違いがもたらされることもあります。
クライアント/サーバーなアプリケーションを例にとれば、サーバーですべてを実行すると、アプリケーションの更新は容易になります。一方クライアント側での実行はレスポンスや切断時の操作を考えると優れています。