【アーキテクチャ】3層アーキテクチャとは

3層アーキテクチャとは
「Webサーバー」「アプリケーション」「DB」の3層構造を3層アーキテクチャと呼ぶ。
- Webサーバー
固定のHTML・CSS・JSなどを返し、プログラムによる処理が必要な場合はアプリケーションに依頼する。 - アプリケーション
プログラムでHTMLやJSONなどを生成して返す。 - DB
データを保存する。

アプリケーション内部の3層アーキテクチャ
アプリケーション内部を3層に分けて整理することがある。
- Webサーバー
- アプリケーション
- プレゼンテーション層
- ビジネスロジック層
- データアクセス層
- DB
3層アーキテクチャの役割分担
アプリケーション内部の各層の役割を整理する。
プレゼンテーション層
アプリケーションの利用者(人間や別のプログラム)とやりとりする
ビジネスロジック層
データアクセス層
DBやファイルなどのデータ保存先とやりとりする。

3層アーキテクチャの実装
プレゼンテーション層(インターフェース層)
- Controller
- 利用者とやり取りをする
- リクエストボディを取り出したり、レスポンスを返したりなど
- DBにinsertなどは Service でおこなう
- 利用者とやり取りをする
- Router
- 特定のURLのリクエストに対してどんなレスポンスを返すか設定する
ビジネスロジック層(アプリケーション層)
- Service
- 他のアプリケーションや他のコードとデータをやりとりするための入れ物クラスをDTOと呼ぶ
- 例えば、Controllerにレスポンスを返却する際にロジックで使用していた(都合の良い型)から指定の返却型に合わせる時にDTOを使用すると整合性がとれて良い
- 実装を進めるとロジックが増え Service 層が大きくなってしまう。これを解消するのがドメインモデルパターン(後述)
- 他のアプリケーションや他のコードとデータをやりとりするための入れ物クラスをDTOと呼ぶ
- まずはプレゼンテーション層でもデータアクセス層でもないのがビジネスロジック層だと考えたら良さそう。
データアクセス層
データアクセス層の実装には以下のようなパターンがある。
- Table Data Gateway
- Repository
- Active Record
3層アーキテクチャとMVCの関係
- 3層アーキテクチャとMVCは1対1で対応しない
- MVCは、プレゼンテーション層のアーキテクチャの一種
- だが、考え方は人それぞれっぽい
- プレゼンテーション層を View, Controller に分離し、ビジネスロジック層とデータアクセス層をなんとなく Model と分ける人もいる(自分もこのイメージに近い)

プレゼンテーション vs ビジネスロジック
日付時間の形式変換
見た目を整えるための日付時刻の変換はビジネスロジックではないとと判断されることが多い。
整形はプレゼンテーション層の役割とするのが良いか。
リクエストの形式チェック
例えば、文字数は決められた範囲内か、必須項目が足りているかなどのチェックなど。
以下のような理由でプレゼンテーション層で行うべきである。
- 利用者とのインターフェースでの約束事に関するチェックであること
- 不正な値はなるべく早く検知し、以降のプログラムに進ませないようにすること
複雑な形式チェック
例えば、SNSで自分にはチェックできないようにする、TODOアプリで過去のTODOは登録できないようにする、など。
以下のような理由でビジネスロジック層で行うべきである。
- プレゼンテーション層は見た目だけに関することだけを知っているべきであり、このような知識は持つべきではない
- ユーザーインターフェースがGUIかAPIかCLIかといったプレゼンテーション層の違いによらず、共通したチェックであると想定されるから

ドメインロジックとユースケース
ビジネスロジック層の処理は2つに分けて考えると整理しやすい。
システム都合ではないコアなルール→ドメインロジック
それ以外→ユースケース
例えばリバーシアプリを例にすると、
- データアクセス層を使って1つ前のターンを取得(ユースケース)
- 盤面におけるかチェック(ドメインロジック)
- 石を置く(ドメインロジック)
- ひっくり返す(ドメインロジック)
- データアクセス層を使って保存(ユースケース)
のようになる。
このように、システムなしで現実世界で同じことをやろうとした時にも登場するルールは、ドメインロジックであると考えられる。

ビジネスロジック層の肥大化を防ぐ
どうしても複雑なビジネスロジックを持つシステムだと Service が肥大化しやすい。
肥大化を防ぐにはドメインモデルパターンを用いるのがよさそう。
トランザクションスクリプトパターン
- データの入れ物と処理を分離する
- 手続き型プログラミング
- Service がドメインロジックとユースケースを担当
デメリットは変更に弱く、Service が肥大化する。
ドメインモデルパターン
- データの入れ物に処理も持たせる
- オブジェクト指向プログラミング
- Model はドメインロジックを担当
- Service はユースケースを担当
変更に強く Service の肥大化を防げる。
Repository パターンが使われる。
Repository パターンとは、ビジネスロジックからデータの保存、復元を別レイヤへ分離することで、コードのメンテナンス性やテストの容易性を高めるパターン。

レイヤードアーキテクチャ
3層アーキテクチャの亜種に、レイヤードアーキテクチャがある。
レイヤードアーキテクチャとは、3層アーキテクチャのビジネスロジック層をアプリケーション層とドメイン層に分離するアーキテクチャである。

層分けと各層の実装方式
層分け
- 3層アーキテクチャ
- プレゼンテーション層、ビジネスロジック層、データアクセス層
- レイヤードアーキテクチャ
- プレゼンテーション層、アプリケーション層、ドメイン層、データアクセス層
各層の実装方式
- プレゼンテーション層
- MVC
- ビジネスロジック層
- トランザクションスクリプトパターン
- ドメインモデルパターン
- データアクセス層
- Table Data Gateway
- Repository

アーキテクチャの組み合わせ
- 3層 + MVC + トランザクションスクリプトパターン + Table Data Gateway
- レイヤード + MVC + ドメインモデルパターン + Repository

設計の観点
- どのように層を分けるか
- 3層
- レイヤード...etc
- 各層をどのように実装するのか
- MVC, MVVM...etc
- ドメインモデルをどう設計・実装するのか