Repositoryパターンにおける、MVC + Service + Repositoryの役割をもう一回整理してみる
最近いろんな技術書を読み始めたり、コード設計的なところを調べてみたりして、
ふわっとなんとなく使っているRepositoryパターンにおける「Model」「View」「Controller」「Service」「Repository」のそれぞれの役割についてもう一回整理してみました。
役割をきちんと分かっていないと、形だけのRepositoryパターンになってしまいきれいなコードが書けなくなってしまいます。
というわけで、れっつごー!
Viewはユーザーと直接触れ合う場所
Viewは役割がわかりやすいので今更書かなくても、、と思ったのですが、一応。
Viewは「画面の表示」「画面表示のための判断・処理」を行う場所です。
LaravelだとbladeやVueやReactなどがよく使われます。
Viewには極力業務ロジックを置かないでください。Viewに置くロジックはあくまで画面表示のために必要なものです。
ControllerはViewとServiceの橋渡し
Controllerは、「Viewからリクエストをもらう」と「Viewにレスポンスを返す」という2つの役割があります。
Viewからリクエストをもらって、処理担当のService君に指示を出す係です。
Controllerには業務ロジックは置かないでください。
ThinControllerと呼ばれるように、Controllerはコードが少ない方が良いです。
Serviceはアプリケーションビジネスルール担当
ビジネスロジックには実は「アプリケーションビジネスルール」と「エンタープライズビジネスルール」の2種類あります。
- アプリケーションビジネスルール ... システムであるがゆえに発生するビジネスルール
- エンタープライズビジネスルール ... システムに全く関係なく存在している業務上のビジネスルール
Serviceは、Controllerから指示をうけてアプリケーションビジネスルール、つまり「システムがゆえに発生するビジネスルール」の処理を担当します。その後必要に応じてRepositoryにDB通信・API通信の処理を指示します。
例えばViewから送られてきた値をDBに保存できるようにデータを加工したりとか、逆にDBから取得してきた値をViewに返しやすいようにデータを加工したりとかがこれに当てはまります。
アプリケーションビジネスルールとエンタープライズビジネスルールについては、こちらを参考にしています。
「ビジネスロジック」とは何か、どう実装するのか
RepositoryはDB通信・API通信担当
RepositoryではServiceから指示をうけて、データベースとのやり取りや外部APIとのやり取りを担当します。
逆にデータベースとのやり取り・API通信以外のことは書かないでください。
たまにDB通信しやすいようにデータを加工する部分をRepositoryに書いてあることがありますが(昔の自分)、それはServiceの担当なので、仕事奪わないであげてください。
Modelはエンタープライズビジネスルール担当
Modelにはコアな業務ルールを置きます。
エンタープライズビジネスルールは、前述したとおり、「システムに全く関係なく存在している業務上のビジネスルール」です。
エンタープライズビジネスルールは、サッカーで言うと「2回イエローカードが出たら退場」、「1回レッドカードが出たら退場」「出場できる選手は11人(例外:レッドーカードで1人退場してしまった場合は10人)」みたいなコアなルールの部分です。
↑の例でいくと「イエローカードが2回」、「出場できる選手は11人」のようにデータと密接に関わることが多いので、エンタープライズビジネスルールはデータを持っているModelに置くと、再利用性が超高まります。
おわりに
- ユーザーがViewからリクエストを送る
- Controllerがリクエストを受け取り、適切なServiceにわたす
- Serviceが処理を行い、必要に応じてRepositoryにわたす
- RepositoryがDB通信やAPI通信を行い、結果をServiceに返す
- Serviceが結果をもとに処理を行い、Controllerに返す
- ControllerからViewにレスポンスを返す
- Viewがユーザーに表示する
役割を理解した上で、このような流れをきちんと頭にいれておけば、それだけで結構高い品質のコードを書くことができます。
というわけで、間違いのご指摘等あればコメントでどうぞ。
Discussion