3層アーキテクチャの基礎とその実践
背景
設計について勉強していく中で Service や Domain など登場人物が多く混乱してきた。そこで今一度3層アーキテクチャとは何であるのか整理するのが目的。
Goal
3層アーキテクチャとは何か、MVCとはなにか説明できること。
どこにどんな処理を書くべきか説明できること。
前提
アプリケーションは以下のサーバー構成からなることが多い。
- Webサーバー
- アプリケーションサーバー
- DBサーバー
Webサーバー
Webサーバーは、ブラウザからのHTTPリクエストに応じて静的(=固定)なWebコンテンツ(HTML、CSS、画像、動画など)を返す。
例えば、Reactのアプリケーションは静的なHTML、CSS、JSファイルとしてビルドされ、Webサーバー(Apache, Nginx, Vercel)によって提供される。
アプリケーションサーバー
アプリケーションサーバーは、プログラムで動的なWebコンテンツ(HTMLやJSON)を生成して返す。
Webコンテンツを返すという点ではWebサーバーと共通しているが、両者の違いは、アプリケーションサーバーではビジネスロジックを適用し、DBサーバーと通信して要求に応え、動的に生成された新しいHTMLやJSONををウェブサーバーへの応答として返す。
通常、Node.js(Express)やPython(FastAPI)などを使用して開発されたAPIを呼び出してデータ層と通信しJSONを返す。
DBサーバー
DBサーバーは、データを保存、管理する役割を持つ。
3層アーキテクチャとは
3層アーキテクチャは人によって意味合いが微妙に異なることがあるように見受けられる。「3層アーキテクチャ」は主として以下2つのどちらかのことを指していることが多い。
- 3つのサーバー構成
- アプリケーションサーバーの内部構成
1は、前述したように、「Webサーバー」「アプリケーションサーバー」「DBサーバー」からなるサーバー構成のこと。
2は、「アプリケーションサーバー」の内部構成のことで、「プレゼンテーション層」「ビジネスロジック層」「データアクセス層」のこと。
個人的には3層アーキテクチャといったら2を指して言っている人が多い気がする。
以降、本記事では3層アーキテクチャは2の意味で使うこととする。
3層アーキテクチャ解説
3層アーキテクチャはアプリケーションサーバーの以下の内部構成を表す。
- プレゼンテーション層
- ビジネスロジック層
- データアクセス層
プレゼンテーション層
プレゼンテーション層は、利用者とやり取りをする層である。
例えば、リクエストボディを取り出したりレスポンスを返したり、特定のURLのリクエストに対してどんなレスポンスを返すか設定 Router を定義したりする。
ビジネスロジック層
システムのコアの部分(ロジック)を持つ層である。
例えばリバーシアプリケーションであれば石をひっくり返す判定などはここに記載することになる。
まずはプレゼンテーション層でもデータアクセス層でもないのがビジネスロジック層だと考えたら良さそう。
ビジネスロジック層の実装方法を考える前に、ビジネスロジック層の処理は2つに分けて考えると整理しやすい。
- ドメインモデル
- ユースケース
ドメインモデルは、GUIアプリケーションだからとかCLIアプリケーションだからといったシステム都合ではないコアなルールのこと。
ユースケースは、システム都合による具体的な操作を表現する。ユースケースは、ドメインモデルを使ってユーザーやシステムの操作を実現する。
さてこのビジネスロジック層は大きく2つの実装方法がある。
- トランザクションスクリプトパターン
- ドメインモデルパターン
トランザクションスクリプトパターンは、手続き型プログラミングで、データの入れ物(DTO)と処理(Service)を分離する。Service がドメインロジックとユースケースを担当するため Service が肥大化しやすく変更に弱い。
ドメインモデルパターンは、ドメインロジックを Model に、ユースケースを Service に分離させるパターンで、Service の肥大化を防ぐことができる。
データアクセス層
DBやファイルなどのデータ保存先とやりとりする。以下のような実装方法がある。
- Table Data Gateway
- Repository
ビジネスロジックからデータの保存、復元を別レイヤへ分離することで、コードのメンテナンス性やテストの容易性を高めるパターン - Active Record
まとめ
- 3層アーキテクチャは、アプリケーションサーバーをプレゼンテーション層、ビジネスロジック層、データアクセス層の3つに分割する設計パターン
- それぞれの層には異なる役割があり、分割することでコードのメンテナンス性や再利用性を向上させることができる
- プレゼンテーション層はユーザーとのやり取りを担当
- ビジネスロジック層はシステムのコアなロジックを処理
- データアクセス層はデータベースやファイルシステムとの通信を行う
Discussion