レイヤードアーキテクチャの物理デプロイと閉鎖/開放レイヤーの整理
「ソフトウェアアーキテクチャの基礎」第10章(レイヤードアーキテクチャ)を読んで整理した内容のメモです。
物理トポロジーの3つのバリエーション
レイヤードアーキテクチャの物理デプロイと閉鎖/開放レイヤーの整理
レイヤードアーキテクチャの物理デプロイには、代表的な3つのバリエーションがある。
-
プレゼンテーション層+ビジネス層+永続化層を1つのデプロイユニットにまとめ、データベース層は外部化
従来型のモノリスWebアプリ(サーバー側でHTMLをレンダリングするタイプ)に近い構成。 -
プレゼンテーション層を単独のデプロイユニットとし、ビジネス層+永続化層をまとめた第二のデプロイユニット、データベースはさらに外部化
フロントエンド(React等の静的ファイル)をCloudFrontなどでホストし、Django等がAPIサーバーとしてビジネス層と永続化層(ORM・マイグレーション含む)を担い、RDS等の外部DBに接続するSPA構成がこれに該当する。 -
4層すべて(データベースも含む)を1つのデプロイユニットに統合
組み込みDBやインメモリDBを使う小規模アプリ・モバイルアプリ・オンプレ製品向け。
Djangoでマイグレーション・テーブル編集を行い、フロントをCloudFrontに静的配置する構成は、2つ目のバリエーションに該当する。
閉鎖レイヤーと開放レイヤー
- 閉鎖レイヤー:リクエストは必ず直下の層を経由しなければならず、レイヤーをスキップできない。レイヤー間の分離(Layers of Isolation)を実現する。
- 開放レイヤー:直下の層をバイパスして、さらに下位の層に直接アクセスすることを許可する。いわゆる「追い越し車線(Fast-Lane Reader)」パターンがこれに当たる。
なぜ開放レイヤー(直接アクセス)が結合を強めるのか
プレゼンテーション層が永続化層に直接アクセスできてしまうと、永続化層の内部実装(テーブル構造・カラム名・ORMのモデル定義など)をプレゼンテーション層が「知っている」状態になり、密結合になる。
例えば永続化層でカラム名の変更やDBMSの移行が発生すると、直接アクセスしているプレゼンテーション層のコードも同時に修正が必要になる。さらに、ビジネス層もそのデータを利用してロジックを組んでいるため、1つの永続化層の変更がビジネス層とプレゼンテーション層の両方に波及してしまう。
間に閉鎖レイヤーとしてビジネス層を正しく挟んでおけば、その契約(メソッドのシグネチャ)が変わらない限り、永続化層内部の実装変更はプレゼンテーション層には影響しない。
アーキテクチャシンクホール・アンチパターン
リクエストが各レイヤーを経由する際、業務ロジック(集約・計算・変換・ルール適用など)が一切加えられず、ただ右から左へパススルーされる状態を「アーキテクチャシンクホール(Architecture Sinkhole)」と呼ぶ。
パフォーマンスへの影響
各層を通過するたびにオブジェクトのインスタンス化やメソッド呼び出しのコストが発生し、これが積み重なるとメモリ消費と処理時間の無駄が増える。1回のリクエストでは大きな差はないが、こうしたパススルーがリクエスト全体の大部分を占めると、システム全体の速度低下につながる。
80-20ルールによる判断
- リクエストの20%程度が単純なパススルー(シンクホール)であれば健全な状態。
- リクエストの80%以上がシンクホールになっている場合、レイヤードアーキテクチャがそのドメインに適していない可能性が高い。
対応策とトレードオフ
一部のレイヤーを開放レイヤーにしてバイパスを許可することでオーバーヘッドを減らせるが、これはレイヤー間の分離を犠牲にし、変更管理を難しくするというトレードオフを伴う。シンプルなCRUD処理が業務の大半を占めるドメインでは、そもそも多層構造自体がオーバーエンジニアリングになっている可能性もあり、モジュラーモノリスのようなシンプルな構成を検討する余地もある。
まとめ
| 概念 | ポイント |
|---|---|
| 物理デプロイのバリエーション | フロントとバック(+DB)の分離度で3パターン |
| 閉鎖レイヤー | 分離を守るが、パフォーマンスコストがある |
| 開放レイヤー | パフォーマンスは良いが結合が強まる |
| アーキテクチャシンクホール | 業務ロジックのないパススルーが多いと発生するアンチパターン |
| 80-20ルール | シンクホール比率の健全性を測る指標 |

