ついにSilverlightの開発に取り掛かり、MVVMに出会いました。私はMVCに精通しており、私が読んでいた記事はXAMLのためにMVCが機能しないと言っていました。 XAMLの経験があまりないことが明らかにこの点を理解できなかった理由です。
なぜMVCが適さないのか、MVVMがSilverlight開発に適しているのはなぜですか?
ありがとうJD
その非常に細かい違いは、ASP.NETのMVCとWPFのMVVMを比較することで最もよく説明できます。
ASP.NET MVCでは、リクエストはWebサーバーから送信され、コントローラーによって直接処理されます。コントローラは適切なビューを決定し、モデルを表示します。次に、コントローラーはこれらのインスタンスを基盤となるシステムに解放し、クライアントに結果をレンダリングします。コントローラが最初にそして最後に動作することがわかります。
MVVMでは、UI(ビュー)はユーザーに向かい、ユーザー入力を直接受け取ります。ビュー内では、ViewModel(ビューのDataContext)内のコマンドがこのアクティビティによってトリガーされます。制御は、Viewが送信したものを解釈してModelを準備するViewModelに流れます。制御がビューに戻った後、モデルの変更に従って自身を更新します。新しいビューが必要な場合、ViewModelはこれをNavigationService(またはアプリケーションが使用するナビゲーションのメソッド)と通信します。これは、ウィンドウまたはフレーム-UIコンポーネントの権限です。 ViewModelが最初で最後ではないことがわかります。ビューはMVCよりもはるかに大きな役割を果たします。
WPF/Silverlightのアーキテクチャは、物事がこのように行われる理由です。コマンド、バインディング、およびナビゲーションインフラストラクチャは、コントローラーによって制御/置換できません。 UIと緊密に統合されています。したがって、コントローラーはビューの下に座って、より受動的な役割を果たす必要があります。
MVVMは主にXAMLのために設計され、データバインディングをさらに単純にするために、MVPと非常によく似ています。主な利点は、ユーザーインターフェイスを操作するより簡単な方法です(ViewModelまたはPresenterは、コントローラーによって操作された後にモデルがビューにイベントを発生させる必要がなく、そのタスクを処理します)。
原則を理解するのに役立った、私が出会った中で最も優れた2つの記事は MVC vs MVP vs MVVM と 私のようなTarded FolksのMVVMまたはMVVMとそれが私に意味すること
デカップリングコンポーネント
MVCでは、コンポーネント間に三角形の関係があります。つまり、コントローラはビューとモデルを所有します。ビューはモデルの定義に依存しています。モデルはビューの要件を満たす必要があります。ハブ(コントローラー)とスポークアーキテクチャ(ビューとモデル)を考える
MVVMでは、各コンポーネントがチェーン内でお互いについてのみ知っている状態で、三角形が平らになっていると考えてください。つまり:View-> ViewModel-> Model
モデルはスタックの何も認識していません。 ViewModelはモデルのみを認識します。Viewはビューモデルのみを認識します-モデルを認識しません。
なぜこれが重要なのですか?
これが元の質問の中核です。
主な目的は、アーキテクチャをさらに抽象化することです。これにより、通常、コードが少し増えますが、オブジェクト間の接点が少なくなります。より機敏なコードにつながるため、連絡先が少ないことが重要です。クラスAとクラスBのカップリング/コンタクトが多いほど、クラスAの変更による影響が大きくなります。変更の影響を軽減することは、優れたアーキテクチャの主な利点の1つです。
これを完全に理解するには、コンポーネントが実際に何を表しているかについて熟考することが役立ちます。ビュー、コントローラー、ビューモデル、モデルとは何ですか?それらは文字通りの定義ですか、それとも抽象的な概念ですか?
私の経験では、モデルをデータの構築と永続性を処理するクラス/オブジェクトのクラスターであると考える方がより有益でした。これは、プロパティを持つ単純な古いオブジェクトではありません。これは、データのフェッチ、データの保存、プレーンな古いオブジェクトを構築するファクトリを実行するクラスです。これは、データへの明確なAPIを提供するファサードレイヤーです。このファサードレイヤーをビューから直接参照する必要がありますか?
私の意見では、そうすべきではありません。 MVCでは、その答えも「いいえ」です。コントローラはモデルからデータをフェッチします。その点で、MVCとMVVMは同じ目標を達成します。 2つのアーキテクチャが異なるのは、データとビューのリンク方法です。
モデルと同様に、ビューはクラスのコレクションであり、相互に連携してプレゼンテーションビューをレンダリングします。これは、モバイルプラットフォームの場合はView Controller + Viewで構成できます(iOSではView Controller、AndroidではActivity)。多くの場合、ビュードキュメントをメモリに読み込み、ビュープロパティを更新するクラスが必要です。ここでやらなければならないことがたくさんあります。 MVCでは、コントローラーはすぐに「キッチンシンク」クラスになります。これは、現在のユーザーコンテキストに関連するあらゆるものの一種のダンプの根拠です。
これをアプリケーション内の数十の潜在的なビューに掛けると、バックエンドのモデルコードとフロントエンドのビューコードの間に多くの深い依存関係が生じます。大きなControllerクラスでは、これらの依存関係はすぐにはわかりません。
依存関係をフラットにする
MVVMは依存関係を平坦化します。これはフォーカスを作成します。フォーカスとは?他のすべての依存関係を邪魔することなく、単一の機能を処理する機能。これで、以前はテスト不可能と見なされていたコードの単体テストの作成を開始できます。
ビューモデルは、ビューとモデルの間のファサードとして機能します。ビューモデルはビューのニーズに応えます-技術的にはビューはビューモデルを所有する必要があります。ビューが複数のソースからのデータを必要とする場合、ビューモデルは個別のデータソースの構成を単一の統一された非正規化オブジェクトにカプセル化します。ビューがモデルまたは他の宛先にコールバックする必要がある場合、ビューモデルはフックを提供し、適切な呼び出しをルーティングします。
ネットワークパッチパネルがどのように機能するかを検討します。一見、これは冗長に思われます-イーサネットをポイントAからポイントBに単純に配線しないでください。しかし、経験から、パッチパネルは、ポイントのルートを変更できるようにする抽象化の重要な部分を提供することを理解します。ポイントAに影響を与えないB。これは、ビューモデルが行っていることです。
ビューとモデルの間に明確な抽象化ができたので、結果として、ビュー/コントローラーはプレゼンテーションのみに関係するようになります。これは、ローカリゼーションやフォーマットを処理するべきではないことを意味します-データを取得してデータを表示します。ビューモデルは、このようなプレビューデータのマッサージを行うのに理想的な場所です。基準に基づいてデータをフィルタリングする必要があるとしましょう。繰り返しますが、ビューモデルはモデルデータについての知識があり(ビューはそうではありません)、この種のコードを配置するのに最適な場所です。
この方法でアプリケーション要件の整理を開始すると、ビュー/コントローラーコードがよりクリーンになり、何かを変更する必要がある場合、その影響がより明確になり、バグが減少します。
テスト容易性
テスト容易性に関する最後の注意:依存関係を平坦化することにより、模擬依存関係をテストに挿入することが容易になります。これにより、テストがより簡単で簡潔になります。ビューモデルは、明確なテストケースを定義できるものになります。
MVVMはMVCよりもXAMLに適しているという考えだと思います。 MVCが「適していない」と言うのは少し誇張されています。
そして、なぜMVVMが優れているのですか?主に、XAMLの優れたデータバインディングとコマンドバインディングが原因です。 この記事 を参照してください。
他の利点は、学習曲線です。フロントエンドテクノロジーのほとんどの開発者はMVVM種類のコーディングスタイルを使用しているため、ビューからコントローラーにすべてのリクエストを渡してモデルと通信させる必要があるコントローラーモデルを使用するよりも、同じ方法を採用する方が簡単です。