📑

Repositoryパターンにおける、MVC + Service + Repositoryの役割をもう一回整理してみる

2021/05/26に公開

最近いろんな技術書を読み始めたり、コード設計的なところを調べてみたりして、
ふわっとなんとなく使っている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に置くと、再利用性が超高まります。

おわりに

  1. ユーザーがViewからリクエストを送る
  2. Controllerがリクエストを受け取り、適切なServiceにわたす
  3. Serviceが処理を行い、必要に応じてRepositoryにわたす
  4. RepositoryがDB通信やAPI通信を行い、結果をServiceに返す
  5. Serviceが結果をもとに処理を行い、Controllerに返す
  6. ControllerからViewにレスポンスを返す
  7. Viewがユーザーに表示する

役割を理解した上で、このような流れをきちんと頭にいれておけば、それだけで結構高い品質のコードを書くことができます。

というわけで、間違いのご指摘等あればコメントでどうぞ。

Discussion