【MVCモデル】初学者がMVCを学んだメモ

MVCについて調査し、学んだことのアウトプットです。
ご指摘などあればコメントにいただけると幸いです。
※ここでは主にDBを持つWebシステムという前提のMVCについて扱います。

#この記事の対象者
・MVCという単語を初めて聞いて、どういうものか知りたい人
・初学者がMVCをどう捉えているか知りたい人


#MVCとはなんなのか？
一言で言うと、**プログラムを整理するモデルの1つ**です。
「ユーザーが視覚的に操作できるシステムは、**Model**と**View**と**Controller**というパーツに分けられるよね」という考え方で、これらを縮めてMVCと言います。

#「M」「V」「C」はそれぞれどんなまとまりなのか？
たとえば、誰もが使ったことがあるAmazonの商品購入ページで考えてみます。
Amazonの商品ページで購入ボタンを押すときの処理の流れです。
（内部の実装は知らないので、MVCに基づいて実装されているという仮定で書きます）

###全体像
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228301/d5e93796-d07a-fe81-0205-49e02f2ed266.png)
全体像はこのようになっています。

流れは以下の通り（不適切な点があればご指摘ください）。


####①商品ページを見せる
モニタを通じてユーザーに商品ページを見せます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228301/5a0f0467-e3e7-f4c9-0404-7492fd32d0e1.png)

商品ページを見たユーザーは購入ボタンの位置を確認します。
####②購入ボタンを押下
ユーザーはマウスカーソルを購入ボタンに合わせてクリックします。
####③購入ボタンが押下された通知
Controllerに購入ボタンが押下された通知を送ります。
システムが処理を開始するトリガーになります。
####④購入ボタン押下に紐づく処理を依頼
通知を受け取ったControllerは、Modelに「購入ボタンが押されたので適切な処理をしてくれ」という依頼を出します。
####⑤DBの処理
依頼を受け取ったModelは、依頼内容に従ってDBの処理を行います。
この場合は、「ユーザーが商品を購入する」というアクションに紐づいたものになるので、
・対象商品の在庫を1減らす
・対象商品の情報を取得する
といった処理をします。
####⑥購入ページの描画依頼
Viewに「購入ページを表示してくれ」という依頼をします。
####⑦商品データの参照
Viewは購入完了ページを描画するために必要な情報を、Modelに取りに行きます。
⑤の段階でDB処理を終えているので、Modelは次のページを描画するのに必要な情報を持っています。
####⑧購入ページを描画完了
取得してきたデータをもとに、Viewは購入完了ページを描画します。


…というような流れになっています。
では、Model View Controllerがそれぞれどういうことをしているのかざっくり把握したところで、言葉で整理していきます。

###**Viewとは？**
Modelから説明するとわかりづらいので、まずはViewについてです。
Viewがいちばん直感的に理解しやすいです。

一言で言うと、**ユーザーに見える部分を描画しているのがView**です。
この場合は**購入完了ページを表示する処理**をしています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228301/c1058709-2e6b-6e03-adab-ebb0df76a201.png)

※デザインパターンの本を買い物かごに追加した後の画面です。これを表示しているのがView。

Viewの仕事は、**システムとユーザーを繋ぐこと**です。
Viewのおかげで「マウスをどれだけ動かしてクリックすれば商品を購入できるのか」や「○○という商品を購入完了できた」などの情報がユーザーに伝わります。


※商品情報が必要なのでDBに繋いで、商品の情報をとってくる、、、というのは**Model**がやっています。Viewはあくまで表示です。「間違いやすい点」で後述します。

###**Controllerとは？**
続いてはController。
**ユーザーからの入力を受け取り、ModelとViewに命令を出しているのがController**です。
言うなれば指揮官のようなイメージです。

この場合では**「購入ボタンを押下する」というユーザーのアクションを受け取り、ModelとViewが処理できる命令に変換する**、という仕事をしています。

Modelには「対象商品の在庫を減らしてくれ」「対象商品の情報を取得してくれ」

Viewには「買い物かごに追加した後の画面を描画してくれ」という指示をそれぞれ出しています。

###**Modelとは？**
調べてみると、

>ビジネスロジック全体を扱っているのがModelです。

という説明をされていることが非常に多いです。

ところが、「ビジネスロジック」という言葉について調査していくと、最終的に**「明確な定義がない」**ことが判明します。

つまり、文脈によって意味が異なるのです。

個人的にいちばんしっくりくるModelの説明は、
**「ViewとController以外の仕事をすべてやっているのがModel」**
というものです。

DBからデータを取得する処理、Viewで表示するためにデータを加工する処理、、すべてModelがやっています。

ここでは
・DBにアクセスして、商品の在庫を1つ減らす
・買い物かごに入れた商品の情報を取得する
という処理を行っています。


#なんのためにMVCにわけるのか？
ここまでMVCのそれぞれのパーツについて説明してきました。
では、なぜわざわざこんな分け方をする必要があるのでしょうか。
理由は大きく2つ挙げられます。
###1.分業しやすくなる
開発チームに「DB周りの処理をつくるのが得意なエンジニア」と、「UIを考えるのが得意なエンジニア」がいるとします。

このとき、システムのソースがMVCで切り分けられていると、前者は「Model」を、後者は「View」を開発すればいいことになります。

それぞれの担当箇所が明確になり、業務効率が上がるというメリットがあります。

このように、チームで開発する際にシステムの各パーツが明確に整理されているのは非常に大切なことです。


###2.保守しやすくなる
「では、個人開発ではMVCに切り分ける意味がないのか」というとそんなことはありません。

MVCでシステムを整理すると、それぞれの機能が独立します。

つまり、**1つの部品を機能変更をした際に他のパーツに与える影響が少なくなります。**

たとえば買い物かごボタンの位置を変えたからといって買い物かごボタンに紐づくDBの処理も変える、、といったことになりません。

ViewにべったりDBの処理も書いてしまっていると、変える必要がでてくる可能性があります（自分が過去につくったシステムはこうなっています）。

#間違いやすい点
###Modelに書くべき処理をViewに書きまくる
自分がはじめて一からシステムを開発した際にやってしまったミスです。
ViewにDBに繋ぐ処理やデータを加工する処理をベッタリと書いていました。

小規模なシステムなので「動けばOK」という思想でつくっていたのですが、この思想だと保守性が極めて低いプログラムができてしまいます。

#まとめ・所感
###・MVCは、プログラム整理モデル
Model View Controllerでプログラムを整理するためのモデル。
分業しやすくすることと、保守性の向上が主な目的。
###・「VCM」って言った方がわかりやすいと思う
ユーザーがViewを見てControllerを操作して裏でModelが処理して…っていう流れを考えると、「VCM」と言った方が直感的にわかりやすいと思いました。
MVCという順序に何か理由はあるのでしょうか？

#参考文献
https://hijiriworld.com/web/mvc-concept/
漫画でわかるMVC
https://www.slideshare.net/MugeSo/mvc-14469802
やはりお前らのMVCは間違っている
https://qiita.com/s_emoto/items/975cc38a3e0de462966a
MVCモデルについて
https://ja.wikipedia.org/wiki/%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF
「ビジネスロジック」Wikipedia
http://at-grandpa.hatenablog.jp/entry/2013/11/01/072636
「MVCの勘違い」について、もう一度考えてみる