MVC の Model を考える

Preview:

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 なんてない方が良かったんだ! ってなることもあるよ!

Recommended