Open8
MVCとADR(Action-Domain-Responder)をざっくりと
mvcの考え方で責務は分けることは出来るが、何も考えずに実装すると境界が曖昧になる。
↓
adr:責務をより限定的にすることで、分かりやすくした
-
adr:ビジネスロジック、リクエスト処理、レスポンス成形を分離する考え
- 互いを疎結合にしたい、その状態を望む
-
mvc:コントローラにリクエスト処理、ビジネスロジック、レスポンス成形が混ざる場合が多い
- 結果としてコントローラ、クラスの肥大化
- コントロール内のメソッドが密結合になりがち
- Model, Domain
- ほぼ同じ、宗教論争になる
- Controller, Action
- 1アクション1クラス
- アクションに対する横断処理、合成処理のやりやすさ
- 神コントローラの誕生を阻止
- View, Responder
- ビューはテンプレートを使うとは限らない(JSON返す時など)
Presentation Domain Separationの原則
- MVCが本当に実現したかったこと
- ドメイン層はプレゼンテーション層に比べ使い回しやすく変更されにくい
- 疎結合にしておくと幸せになれる
ビューの役割
- ドメイン(モデル)層の処理結果をユーザーにどう見せるかを決めるロジック
- クライアントが違えばどう見せるべきかも変わる
- ブラウザ、コマンドライン
Webアプリケーションの”ビュー”
- ユーザーモデル($userなどドメインの出力)→変換→HTTPレスポンス(HTML, JSON, etc.)
- テンプレート→レスポンスボディのみ
- ビューはステータスコード、HTTPレスポンスヘッダも扱うべき対象となる
ControllerにWebアプリケーションでの”ビュー”の処理(責務)が混在してる
ステータスコード、HTTPレスポンスヘッダなど
public function show($user_id, UserShowUseCase $useCase)
{
$user = $useCase->run($user_id);
// ここから
if (is_null($user)) {
return response('Not Found', 404);
}
return view('users.show', ['user' => $user]);
// ここまで
}
Responder
- クラスを定義することでHTML, JSONなどでResponderを入れ替えることで出しわけ可能
- Domainは使い回すことができる→疎結合、責務の分離ができる
まとめ
- ADRはMVCが本当にやりたかったこと
- Webアプリケーションでの”ビュー”はHTTPレスポンスを生成する処理のこと
- テンプレートだけが”ビュー”ではない
ADRパターンのデメリット
- Actionのファイルに1つ1つコンストラクタ注入を書くのがだるい
- 複数のActionでメソッドを共有するときControllerでprivateメソッドのような楽ができない
- Responderクラスをいちいち作るのが面倒
- 処理がController以外に分散して一覧性が悪い
ADRとMVCの中間は?
- Controllerの分割
- ControllerクラスのままでResponderの導入
原典
サンプルリポジトリ
Repositoryパターンを採用する際のEntity, Service, Repositoryの棲み分け
- Service:アプリケーションビジネスルール担当
- Repository:DB、API通信の担当(Serviceから呼び出される)
- Entity:エンタープライズビジネスルール担当
おまけ(Webサービスを前提とする)
- Responder:HTTPレスポンスの成形(ヘッダ、ボディなど)
- Action:ServiceとResponserの橋渡し(リクエスト→処理:Service→レスポンス:Responder)