MVC の
Model について
考える
codeArts (株) 政倉 智
MVC ってこんなの
ModelModel
ControllerController
ViewView
でも、こんなんなってません?
ModelModel
ControllerController
ViewView
Controller が太るんです
● MVC って変更に強いはずなのに、なんかうまくいかない!
ちょこっとしたことですぐ動かなくなる!
● こういう時はだいたい Controller にコードが集中していて
太っている時
MVC と三層アーキテクチャの対比
ModelModel
ControllerController
ViewView
データ層
ドメイン層
プレゼンテーション層
Model はドメイン層
● MVC の Model はドメイン層 (ビジネスロジック) にあたる
● Controller が太るのは、このドメイン層のコードを
Controller に書いているから!
なんでそうなるのか?
● だって MVC のチュートリアルがそうだもの!
● Model をデータストアにして処理は Controller に書かれて
る
なぜ Controller に書くとダメなの?
● そもそもなぜ Controller に書いてはいけないのか
MVC はだいたいこんな感じ
● 基本的に Controller は View の設計に引きずられる
● Model はアプリの機能に引きずられる
View A
View B
Controller A
Controller B
Model
Controller にビジネスロジックを書
く
● ドメイン層 (ビジネスロジック) を Controller に書くとこ
んな感じになる
View A
View B
Controller A
Controller B
Model
ビジネスロジック
View A が必要なくなった!
● View A が必要なくなったとする
View A
View B
Controller A
Controller B
Model
ビジネスロジック
あっ!
● 連鎖的に Controller A が要らなくなるけど、ビジネスロ
ジックまで消えちゃう!
View A
View B
Controller A
Controller B
Model
ビジネスロジック
しくしく...
● ビジネスロジックを Controller B に移動するはめに...
● ちなみにこれ、テストコードも同時なので最悪のパター
ン!
View A
View B
Controller A
Controller B
Model
ビジネスロジック
ビジネスロジック
Model に書いておけば
● Model にビジネスロジックを書くと良いよ
View A
View B
Controller A
Controller B
Model
ビジネスロジック
View A を消しても大丈夫
● View A を消しても大して影響がない
● 少なくとも View B には一切影響がないね!
View A
View B
Controller A
Controller B
Model
ビジネスロジック
ビジネスロジックは Model に!
● というわけでビジネスロジックは Model に書きましょう
● AngularJS の場合は Factory という便利なものがあって、
それを使いましょう
Model がでかくなるだけじゃ?
ModelModel
ControllerController
ViewView
実際そうなんです
● 今度は Model がでかくなってひーひー言います
● でも、Controller が太るよりマシです
● なぜマシかというと、Model は Controller と違って View
の変更の余波を受けにくいからです
小さく分割しましょう
● Model という一つのオブジェクトに色々させるのではな
く、役割ごとに分割しましょう
● Controller から見て Model が一つのオブジェクトに見えれ
ば OK! その向こうにたくさんのオブジェクトがあっても
問題ない
例) キャッシュ
● サーバーから JSON データをも
らって表示するだけの簡単なア
プリ
● まずはキャッシュしないのを
サッと作る
● View は割愛
Controller
Model
BaaS
例) キャッシュ
● キャッシュ機能をつけてみる
● 肝はもともとある Model に
キャッシュ機能をつけようとし
ないこと
● まずは Model を BaaS に接続す
るものと、それを呼び出す二つ
に分ける
Controller
Model
BaaS
BaaS Client
例) キャッシュ
● BaaS Client と同じ API を持つ
Cache System を作る
● BaaS Client と Model の間に
Cache System を挿入する
● Controller から直接見える
Model が変わっていないのがミ
ソ
● ほとんどのコードは追加なの
で、とても楽
Controller
Model
BaaS
BaaS Client
(Model)
Cache
例) 新着通知
● Facebook とかの新着通知です
● 投稿だったり、チャットだったり、いろいろあります
投稿
(Model)
チャット
(Model)
新着
(Controllerl)
チャット
(Controllerl)
例) 新着通知
● よく考えたら新着通知って何箇所かあったりするよね!
● 数付き数値アイコンと新着リストみたいな感じの
投稿
(Model)
チャット
(Model)
新着数表示
(Controllerl)
新着リスト表示
(Controllerl)
チャット
(Controllerl)
例) 新着通知
● 見ての通り似たような処理が Controller に書かれている
● これがまた変更に弱くする
投稿
(Model)
チャット
(Model)
新着数表示
(Controllerl)
新着リスト表示
(Controllerl)
新着を抽出する
新着を抽出する
チャット
(Controllerl)
例) 新着通知
● こんな感じに新着情報を扱う Model を作ると楽になる
投稿
(Model)
チャット
(Model)
新着数表示
(Controllerl)
新着リスト表示
(Controllerl)
新着
(Model)
チャット
(Controllerl)
MVC の役割
● Model/View/Controller という役割のクラスがあるのではない
● クラスが Model/View/Controller のいずれかに分類される
● Controller がたくさんの Model を扱うとかはあんまよくない
● Model や Controller が複数のクラスから構成されていても全く問題
ない
● AngularJS で .controller で宣言したものだけが Controller っていう
わけじゃないよ!
● Backbone.js で Backbone.Model を継承した型だけが Model ってい
うわけじゃないよ!
まとめ
● MVC のチュートリアルに惑わされないようにしよう!
● MVC Framework の使い方よりも MVC の利点を理解しよ
う!
● MVC Framework は大枠を提供するためのもの、その大枠
の中でさらにクラスを分割していくのはプログラマーのお
仕事
● 余談だけど、似非 MVC で書くと、最悪は MVC
Framework なんてない方が良かったんだ! ってなることも
あるよ!

MVC の Model を考える