ViewModel不要論について
MVVMにおいてVMが不要という論
VMがないとなるとModelとViewModelのMVでソフトウェアを構成する事になる。
UIのあるソフトウェアにおいてプレゼンテーションロジックがないものは存在しない。
MVアーキテクチャの場合、プレゼンテーションロジックをどこかに置かなければならない。
・Modelに置く場合
ViewにバインドするプロパティをModelに用意することになる。
Model内にUIの制御プログラムが存在する事になり、
UIとUI部分を分離するという目的が達成できなくなる。
・Viewに置く場合
ViewにUIの制御プログラムが存在することになり、
UIの見た目とコードを分離するという目的が達成できなくなる。
MVVMの基本的な考え方
・ViewはUIの見た目のみ決める。
プレゼンテーションロジックとは何か
プレゼンテーションロジックとは何かがわからないために
MVVMのViewModelの意味、役割がわからないと思われる。
プレゼンテーションロジックとはUIを制御するプログラム
UI要素に直接アクセスするプログラムはプレゼンテーションロジックになる。
WPFのMVVMで説明する。
ViewにLabelを一個配置
ViewModelにLabelにバインドするプロパティAがある。
プロパティAはViewという具象を抽象化したものであり、Viewの抽象に
直接アクセスして制御するプログラムはプレゼンテーションロジックになる。
Modelからデータを読み取りバインドするプロパティに代入するだけの
プログラムもプレゼンテーションロジックである。
Viewのためのプロパティにアクセスするものはすべてプレゼンテーションロジック
誤解されているViewModel
・ViewModelはViewの抽象化である
wikiにも記載されている言葉であるが、
抽象化は何のためにあるか。誰のための抽象化なのかの観点から考えると
抽象化する意味とは具象に直接さわらないで抽象化してアクセスする。
Viewを抽象化してアクセスするのは誰か?
ここで間違えやすいのはModelがViewをViewModelで抽象化してアクセスするという方式。この方式もありだが、直接的ではないが間接的にViewを制御していることになるので、UIとUI以外を分離した意味がなくなる。
Viewを抽象化してアクセスするのはViewModel自身
ViewModelの中から見て、Viewの抽象化が見えている。
ViewModel = View抽象化層 + ViewModelロジック
ViewModelはViewの抽象化を含んでいるが正しいと思われる。
抽象化という言葉自体が誤解を与える表現と思われる。
・ViewModelはViewをモデリングしたものである。
Viewの抽象化ということでViewをモデリングしたものがViewModelであるという
のと、View”Model”という言葉からモデリングしたものという考えだと思わるが、
Modelにはソフトウェアの中核のデータとロジックという意味もある。
Viewのためのデータとロジックという理解が正しいと思われる。
・ViewModelはUIの都合を隠すためにいる
ViewModelの役割がこれしかないと考えている人がViewModelを不要と判断する場合がある。
WPFの場合、UIスレッド以外のスレッドからコントロールに直接アクセスすると例外がおこる。
このUIの都合はバインド機構が肩代わりしてくれている。
バインドするプロパティを用意すれば自動的に表示更新を行ってくれる。
プロパティはただの変数なのでUIスレッド以外からもアクセスできる。
ViewModelはバインドするプロパティを用意しているだけであり、UIの都合を隠すためにViewModelが何かをやっているわけではない。
Modelにバインドするプロパティを置けば動くものはできるがMVVMではない。
MVになるだけである。Model内にViewの抽象化を抱え込む形になる。
UIとModelの分離するのがViewModelの仕事である。ViewModelにはViewModelの仕事がある。
・ViewModelがバインドしている
他でバインドしているからViewModelはいらない。
ViewModelがバインドしているわけではない。
ViewModelはバインドするプロパティを用意しているだけ。
他でバインド機構が動いていたとしてもViewModelの役割はある。
・ViewModelにはロジックを書かない
ViewModelにビジネスロジックは置かない。という言葉が誤解されて広まったものと
考えられるが。UIロジックは置かなければいけない。
ViewにはUIロジックは置かない。
ModelはUIを知らない。
UIロジックの置き場はViewModelしかない。
・ViewModelはViewとModelの橋渡し
橋渡しだけなら、無くてもいいだろうという考えもあるが
ViewModelの役割
・VIewへバインドするプロパティ、コマンドを用意する。
・Modelのデータを変換してView用のデータにする。
・Viewのロジック
橋渡しだけが仕事ではない。
Modelメソッドの戻り値はvoidでなくてよい
voidの場合もあるし、戻り値がある場合もある。絶対的な決まりがあるわけではない。
voidの場合
1.ただメソッド実行したいだけで戻り値がいらない。
例)Model.Start();
2.メソッド実行して、非同期に動作する場合
非同期に動作するのでメソッドの戻り値はvoidでよい場合もある。
イベントで動作完了を報告する。
メンバ変数で動作完了を報告する。
反例)
実行開始成功したかどうかを返す場合もありうる。
設計しだいでケースバイケース。絶対的な指針ではない。
MVVMのよくある誤解
・Modelはデータのみ。
-> Modelの仕事をViewModelが奪っている。
・ViewModelからネットワークアクセス
-> ネットワークアクセスはUIの仕事ではない。
・ViewModelはViewのデータを用意するだけ、
-> Viewにプログラムはない。
よって、
例)
・textbox入力のバリデーション(
・ボタンのイネーブル/ディセーブル
・メニューチェックマーク
・ModelからViewModel,Viewにアクセスする。
-> ModelがUIに依存している事になるのでUI処理とUI処理
・VVM ModelなしでViewとViewModelで構成する。
-> 間違いではないが、MVVMではない。
表示+入力 と それ以外は分離できるが、
・Modelのメソッドの戻り値は当然voidである。
-> voidの場合もあるし、戻り値を返す場合もある。設計による。
WPFのMVVMとは何か
UIとUI以外を分離するアーキテクチャー
アプリケーション = UI処理 + UI処理以外
UI処理以外をModelと呼ぶ。
アプリケーション = UI処理 + Model
UI処理の中をViewとViewModelに分離する。
アプリケーション = View + ViewModel + Model
アプリケーションのすべてのプログラム、データはView,
View,ViewModel,Modelの依存は一つのみ。
View -> ViewMdel -> Model
(ViewはViewModelに依存、
・View
Viewは画面表示と入力を担当する。
ViewはViewModelを知っている。
=
=ViewはViewModelにアクセスできる。
Viewの表示するデータはViewModelが持つ。
Viewの入力処理(Command)
・ViewModel
ViewModelはUIの中の表示と入力以外全部を担当する。
ViewModelはViewを知らない。
=
=ViewModelはViewにアクセスできない。
Viewの表示するデータはViewModelが持つ。
Viewの入力の対応処理プログラム(Command)
UIとModelの橋渡しをするのはViewModelの仕事。
ViewModel = データ + プログラム
ViewModelの仕事
Viewとのやり取り
UIの仕事
Modelとの橋渡し
だけ
ViewModelがViewに公開するもの
プロパティ
Command
NotifyChangedイベント
ViewModelはModelを知っている。
=
=ViewModelはModelにアクセスできる。
ViewとViewModelをつなぐのはバインド機構
バインド機構はアプリーケーションの外側
・Model
Model = データ + プログラム
ModelはViewModelを知らない
= ModelはViewModelのインスタンスの参照を持たない
= ModelからViewModelにアクセスはできない。
Modelが公開するもの
メンバ変数
プロパティ
メソッド
デリゲート
イベント
ViewModelとModel間については規定はない。
ModelはUIが切り替わっても動作できるように作ってもよい
重要なのはUIとUI以外を分離すること。