はじめに
この記事が面白かったのですが、この手の話は信じる宗教の違いが大きく絡むためコメントを付け始めると宗教戦争が始まって不毛になり易いし、どうやっても普遍的な答えは導き出されないと思うので、この記事を下敷きにしながら「ぼくのかんがえるMVCべからず集」をまとめてみようと思います。他の人の考える「ぼくのかんがえるMVCべからず集」も読んでみたいです。
前提となる「ぼくのかんがえるMVC」
- MVCはそれぞれ「層」ではなく「コンポーネント」である
- MVCはそれぞれが協調して動くものであると考えている
Model
Modelは所謂業務ロジックのコンポーネントです。目安として「動かすプラットフォームやアプリケーションの形態(ex:Web, Native)が変わっても、不変なロジック」がModelです。ここで言うModelはDBのことを指しません。勿論ORマッパのことをModelと呼んでる訳でもありません。
DBにアクセスしていいのはModelだけ- 他のデータとの整合性など最終確認はModelで。
テストファーストで書く- ここでprintとか絶対NG
- ここでWebサーバ由来の情報(SESSIONなど)があったら、何か間違ってる
差分について
「DBにアクセスしていいのはModelだけ」ではない
必要であればViewからも直接DBを見に行けるべきです(ORマッパやDB周りのライブラリを通じて)。Viewが単純に表示したいだけの都合でModelやControllerが影響を受けるべきではない。
必ずしも「テストファーストで書く」必要はない
UnitTestは有った方が良いですが別にテストファーストでなくても良いと思います。
勿論、テストファーストが悪い訳ではありません。
View
テンプレートとテンプレートに渡すデータを作る機能をまとめてViewであると考えています。
ここでDBにアクセスしてたら何か間違ってるここでIF文とかあったら、Controller側ですべきか検討する
差分について
「ここでDBにアクセスしてたら何か間違ってる」訳ではない
Modelで触れている通りです。話をテンプレートに限定しているならば、そんなところでアクセスすべきではないという意見は一致します。ただ、Viewというコンポーネントは自分が表示したいだけの情報の取得はViewが受け持つべきだと考えます。
必ずしも「ここでIF文とかあったら、Controller側ですべきか検討する」必要はない
Viewの都合をContorllerが受け持つ必要はありません。
Controller
そのURLがそのURLである責務を果たすためのコンポーネントのことだと考えています。例えば「/me」というURLが有る時、Controllerはログインチェックをして非ログインであれば、ログインフォームへリダイレクレトし、ログイン中であればSessionからユーザーのIDを抜いて、Userを管理するモデルへIDを渡し、情報を受け取り、期待されるRequestがHTMLであればViewに渡し、JSONであればJSONをシリアライズする機能に渡すようなコンポーネントです。
ここでDBにアクセスしてたら何か間違ってるここでバリデーションとかしてたら、何か間違ってる
差分について
必ずしも「ここでDBにアクセスしてたら何か間違ってる」訳ではない
Controllerの役割としてのDBアクセス(ORマッパやDB周りのライブラリを通じて)であれば全力で行うべきです。
とは言え、そういったケースは少ないかも知れません。
「ここでバリデーションとかしてたら、何か間違ってる」訳ではない
業務ロジックとしてのバリデーションはModelがするべきであると考えます。しかし、そのControllerが期待しているrequiredであったりデータ型のチェックのようなバリデーションは、Controllerがするべきだと考えます。