私はそれをこのように考えるのが好きです:
あなたが言うように、ビューはばかげています。MVVMに関する独創的で頻繁にリンクされているMSDN記事のライターであるJoshSmithは、ビューは「データが着る服」であると述べています。ビューに実際にデータが含まれたり、データを直接操作したりすることはありません。ビューモデルのプロパティとコマンドにバインドされるだけです。
モデルは、ビジネスオブジェクトと同様に、アプリケーションのドメインをモデル化するオブジェクトです。アプリケーションはミュージックストアですか?おそらく、モデルオブジェクトはアーティスト、アルバム、曲になります。アプリケーションは組織図ブラウザですか?おそらく、モデルオブジェクトはマネージャーと従業員になります。これらのモデルオブジェクトは、いかなる種類のビジュアルレンダリングにも関連しておらず、それらを配置するアプリケーションにも直接関連していません。モデルオブジェクトは、ある種を表すオブジェクトのファミリとして、それ自体で完全に意味をなす必要があります。ドメインの。モデルレイヤーには通常、サービスアクセサーなども含まれます。
これにより、Viewmodelsが表示されます。彼らは何ですか?これらは、GUIアプリケーションをモデル化するオブジェクトです。、つまり、ビューで使用されるデータと機能を提供します。これらは、構築している実際のアプリケーションの構造と動作を定義するものです。モデルオブジェクトの場合、ドメインは選択したドメイン(ミュージックストア、組織図ブラウザーなど)ですが、ビューモデルの場合、ドメインはグラフィカルアプリケーションです。ビューモデルは、アプリケーションが実行するすべての動作とデータをカプセル化します。それらは、オブジェクトやリストをプロパティとして公開するだけでなく、コマンドなども公開します。コマンドは、それを運ぶオブジェクトにラップされた単なる動作(最も単純なメソッド呼び出し)です。ビューは、オブジェクトにビジュアルコントロールをアタッチするデータバインディングによって駆動されるため、このアイデアは重要です。MVVMでは、ボタンにクリックハンドラーメソッドを指定しません。
私にとって、最も紛らわしい点は次のとおりです。
- ビューモデルはグラフィカルアプリケーションのモデルですが、視覚的な概念を直接参照したり使用したりすることはありません。たとえば、ViewModelsでWindowsコントロールへの参照を必要としない場合、それらはビューに表示されます。ViewModelは、データと動作を、それらにバインドするコントロールまたはその他のオブジェクトに公開するだけです。たとえば、リストボックスを含むビューはありますか?あなたのビューモデルには、ほぼ確実に何らかのコレクションが含まれています。ビューにボタンはありますか?ビューモデルには、ほぼ確実にいくつかのコマンドが含まれています。
- 「ビューモデル」と見なすことができるオブジェクトにはいくつかの種類があります。理解するのが最も簡単な種類のビューモデルは、1:1の関係でコントロールまたは画面を直接表すものです。たとえば、「画面XYZにはテキストボックス、リストボックス、および3つのボタンがあるため、ビューモデルには文字列、コレクション、と3つのコマンド。」ビューモデルレイヤーに適合する別の種類のオブジェクトは、モデルオブジェクトのラッパーであり、モデルオブジェクトに動作を与え、ビューでより使いやすくします。ここで、「厚い」および「薄い」ビューモデルレイヤーの概念を理解します。「薄い」ビューモデルレイヤーは、モデルオブジェクトをビューに直接公開するビューモデルのセットです。つまり、ビューは最終的にモデルオブジェクトのプロパティに直接バインドされます。これは、単純な読み取り専用ビューなどで機能します。しかし、各オブジェクトに関連付けられた動作が必要な場合はどうでしょうか。モデルはアプリケーションに関連しておらず、ドメインにのみ関連しているため、モデルにそれを含める必要はありません。モデルオブジェクトをラップし、よりバインディングに適したデータと動作を提供するオブジェクトに配置できます。このラッパーオブジェクトもビューモデルと見なされ、それらを持つと「より厚い」ビューモデルレイヤーになり、ビューがモデルクラス上の何かに直接バインドされることはありません。コレクションには、モデル自体を含めるだけでなく、モデルをラップするビューモデルが含まれます。モデルオブジェクトをラップし、よりバインディングに適したデータと動作を提供するオブジェクトに配置できます。このラッパーオブジェクトもビューモデルと見なされ、それらを持つと「より厚い」ビューモデルレイヤーになり、ビューがモデルクラスの何かに直接バインドされることはありません。コレクションには、モデル自体を含めるだけでなく、モデルをラップするビューモデルが含まれます。モデルオブジェクトをラップし、よりバインディングに適したデータと動作を提供するオブジェクトに配置できます。このラッパーオブジェクトもビューモデルと見なされ、それらを持つと「より厚い」ビューモデルレイヤーになり、ビューがモデルクラス上の何かに直接バインドされることはありません。コレクションには、モデル自体を含めるだけでなく、モデルをラップするビューモデルが含まれます。
うさぎの穴はさらに深くなります-MVVMを機能させ続けるValueConvertersのように理解すべきイディオムはたくさんあり、ブレンド可能性、テスト、アプリでデータを渡す方法などについて考え始めるときに適用することがたくさんあります。各ビューモデルは必要な動作にアクセスできますが(これが依存性注入の出番です)、うまくいけば上記が良いスタートです。重要なのは、ビジュアル、ドメイン、実際のアプリケーションの構造と動作を3つの異なるものとして考えることです。