読者です 読者をやめる 読者になる 読者になる

わざわざ残す必要もないことを整理とか気にせずに吐き出していく。そんな空間。

WEBのMVCを分解してみたりまとめ直してみたり

PHP

 WebのMVCってややこしいよねぇ。一旦個人的にまとめときたかったので。

 注意

 大半は独自解釈です!!ツッコミ待ちですので「ここはこうじゃね?」みたいなトコは優しく突っ込んでください。罵詈雑言は中の人が泣きます。

Controller

 コントローラ。これ、Webにおいては基本的にエントリポイントになる。ほっとくと膨れる肥満体質。

着眼点

 スキニーコントローラ設計のPointとしては,書ける,書けないの判断、そして書くべき,書かざるべきの判断。なんでもかんでも外に出しちゃうと,今度は逆にコントローラの意味なくなってくる(ただのディスパッチャになる)。

  • コントローラにしか書けない処理
  • コントローラの外でも書ける処理
    • コントローラに書いたほうが良い処理
    • コントローラの外に書いたほうが良い処理

分類

 一般的にコントローラの担当となる処理一覧

  • エントリポイント: ディスパッチャの矛先
  • 制御: 異常系等の根本的な呼び出しフローの制御
  • 呼び出し: ViewとかModelを呼び出す(Viewを呼ぶかについては異論有ると思う)
  • パラメータの正規化

Model

 処理の根幹を担うところ。あくまで「処理」であって「出力」ではないってのが個人的な考え。出力先がスマホだろうがPCだろうがConsoleだろうがModelはそういうこと基本的に気にしない。データの形式という上で抽象的で有るべき、というのが基本的な考え

  • Component: 主に処理をまとめたもの
    • DAO : DB関連の処理をまとめたものを一般的にこう呼ぶ
  • Entity: 主にデータをまとめたもの

 Componentは責任範囲を明確に,かつ単体でテストしやすい形を考慮する。部品ごとの依存関係は極力排除して存在する場合にはそれを何らかの形で明示化したい。Componentの中で階層化があってもいいと思う。

  • ModelController: より「機能/仕様ベース」な観点で記述されるもの。
  • ModelModel: より「処理系ベース」な観点で記述されるもの。DAOとか。

 Controllerは抽象的な「ModelModel」には直接触れず,すべてModelControllerを経由してModelにアクセスする。「ModelModel」は単に処理を記述するだけで細やかな仕様については考慮されない。仕様の変更等はModelController側で極力吸収すると言った形。

 EntityはViewなどで用いるデータの集合体。連想配列でもいいけど,処理系を含めるならクラスの方が便利。Entityの処理系とかはなんかもうViewModelとの垣根がホントにわかりにくいけど....

View

 Viewは「出力」に携わる部分。テンプレートはそのイチ要素でしか無い。もうちょっとViewは高機能であってしかるべき。

  • ViewController: テンプレート階層の管理だったり,テンプレート変数の管理だったり。後処理,前処理とか。
  • ViewModel: テンプレートに変数を当て込む際の,出力側寄りの処理を担う。Entityとの垣根が難しい。
  • テンプレート: 変数をはめ込むだけの穴あきテンプレート

 ViewController部分の処理はFWの仕様レベルでControllerのドメインになっちゃってる事は多い。ModelとViewをしっかり分離するなら,Modelは出力を意識しない設計になってくるので,出力ドメインレベルの処理はViewが担当しなきゃならない。ということでやっぱりViewModelは必要。

 この辺りまで来ると

テンプレート変数はViewがModelから取得するのか、ModelがViewに割り当てるのか,それともModelがController経由でViewにリレーするのか。

とかいう心底どうでも良い疑問が挙がってくる。このへんについては一応、

  1. 必要が無いならControllerが中継する必要はない
  2. 制御系はControllerの担当。
  3. Modelが特定のView構造にアクセスするのはなんかおかしい

という点をベースに,制御系に関わるデータの取得はControllerを経由して。そうでないならViewが直接取りに行く。という方式を考えている。

 例えば,ブログの場合,記事のデータをDBから取得するのはパラメータを変数としたModelコール。ここの戻り値はHTTP404か200かを決める重要な問題。よってコレは制御系の変数であるからControllerがリレーするべき。

 逆にページングとかもパラメータを変数としたModelコールだけど,制御系には影響を及ぼさない。これはView側が直接Modelにお伺い立てる。

 テンプレート変数の取得方法がController経由のリレーとViewによる自力獲得の2パターン有るのは確かにややこしいかもしれない。制御系に影響する変数はModelがContollerとViewの双方に渡して,Viewが常に変数を自力に取ってくる…という構造も考えたけど,2回モデルをコールするのはコストになるし,そこのコストをなくすために内部でストックして…とか言うのはなんかPHPっぽくない気がするのです。

あとがき

 趣味で開発する時は各クラスを擬人化して,キャラ付けをしっかりとしていくようにしています。Controllerちゃんは真面目な委員長タイプ、DAOちゃんは内気で気弱なグズっ子だからControllerちゃんとはお話できない。みたいな感じ。結構楽しいですがコードコメントにそういうことまで書いちゃうのはどうかと思うので,ちょっと自重します。