Upload
tomomasakura
View
119
Download
4
Embed Size (px)
Citation preview
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 なんてない方が良かったんだ! ってなることもあるよ!