web-dev-qa-db-ja.com

MVCとMVVMの違いは何ですか?

標準の "Model View Controller"パターンとMicrosoftのModel/View/ViewModelパターンに違いはありますか?

1216
Bjorn Reppen

MVC/MVVMはeither/orの選択肢ではありません。

ASP.NetとSilverlight/WPFの両方の開発で、2つのパターンがさまざまな方法で現れます。

ASP.Netの場合、MVVMはビュー内のデータを双方向バインドに使用します。これは通常、クライアント側の実装です(例:Knockout.jsを使用)。一方、MVCは懸念を分離する方法ですサーバー側

SilverlightとWPFの場合、MVVMパターンはより包括的であり、MVC(またはソフトウェアを別の責任に編成する他のパターン)の代わりとして機能するためにappearが可能です。このパターンから頻繁に出てくる1つの仮定は、ViewModelMVCのコントローラーを単に置き換えたことです(頭字語でVMCに置き換えることができるかのように)そしてすべてが許されるでしょう)...

ViewModelはnotを実行して、個別のコントローラーの必要性を必ず置き換えます。

問題は、独立してテスト可能*であり、特に必要に応じて再利用できるようにするために、ビューモデルはどのビューがそれを表示しているかわからないが、さらに重要なことですデータの出所がわからない

*注意:実際には、コントローラーは単体テストを必要とするほとんどのロジックをViewModelから削除します。 VMはその後、テストをほとんど、またはほとんど必要としないダムコンテナーになります。 VMは設計者とコーダーの間の単なるブリッジであるため、これは良いことです。したがって、シンプルに保つ必要があります。

MVVMでも、コントローラーには通常すべての処理ロジックが含まれ、どのビューモデルを使用してどのビューにどのデータを表示するかを決定します。

これまでに見てきたことから、XAMLコードビハインドからコードを削除するViewModelパターンの主な利点XAML編集をより独立したタスクにする。必要に応じて、アプリケーションの全体的なロジックを制御する(しゃれなし)コントローラを作成します。

従う基本的なMVCVMガイドラインは次のとおりです。

  • ビューデータの特定の形状を表示。データがどこから来たのか、彼らにはわかりません。
  • ViewModels 特定の形状のデータとコマンドを保持する、データやコードがどこから来たのか、どのように表示されたのかはわかりません。
  • モデル実際のデータを保持(さまざまなコンテキスト、ストア、またはその他のメソッド)
  • コントローラーはイベントをリッスンし、公開します。コントローラは、表示するデータと場所を制御するロジックを提供します。コントローラは、ViewModelにコマンドコードを提供して、ViewModelを実際に再利用できるようにします。

また、 Sculpture code-gen framework はMVVMとPrismに類似したパターンを実装し、コントローラーを広範囲に使用してすべてのユースケースロジックを分離することにも注意しました。

コントローラがView-modelsによって廃止されるとは思わないでください。

このトピックに関するブログを開始しました。このブログはいつでも追加できます 。ほとんどのナビゲーションシステムは単にビューとVMを使用するだけなので、MVCVMと一般的なナビゲーションシステムの組み合わせには問題がありますが、これについては後の記事で説明します。

MVCVMモデルを使用する追加の利点は、アプリケーションの存続期間中にコントローラーオブジェクトのみがメモリに存在する必要があるであり、コントローラーには主にコードと小さな状態データが含まれていることです(つまり、小さなメモリオーバーヘッド)。これにより、ビューモデルを保持する必要があるソリューションよりもメモリ消費量の少ないアプリが作成され、特定の種類のモバイル開発(Silverlight/Prism/MEFを使用するWindows Mobileなど)に最適です。もちろん、応答性のために時々キャッシュされたVMを保持する必要があるため、これはアプリケーションのタイプに依存します。

注:この投稿は何度も編集されており、質問の幅が狭いことを特に対象としていませんでした。以下のコメントでの議論の多くは、ASP.Netのみに関連しており、全体像には関連していません。この投稿の目的は、Silverlight、WPF、ASP.NetでのMVVMの広範な使用をカバーし、コントローラーをViewModelsに置き換えないようにすることです。

659
Gone Coding

これらの頭字語が何を意味するのかを理解するための最も簡単な方法は、それらをしばらく忘れることです。代わりに、彼らが生み出したソフトウェア、それぞれについて考えてください。それは本当に初期のWebとデスクトップの間の違いに煮詰まります。

最初の頭字語、MVCは、Webで始まりました。 (はい、それは以前からあったかもしれませんが、ウェブはウェブ開発者の大衆に普及した方法です。)データベース、HTMLページ、およびその間のコードを考えてください。 MVCに到達するために、これを少しだけ洗練してみましょう。»database«の場合、databaseとインターフェースコードを仮定しましょう。 »HTMLページ«では、HTMLテンプレートとテンプレート処理コードを仮定しましょう。 「コードの中間」については、ユーザーのクリックをアクションにマッピングして、データベースに影響を及ぼし、他のビューが表示されることを確実にすると仮定しましょう。少なくともこの比較のためには、これで終わりです。

今日のものではなく、JavaScriptが低く卑劣な煩わしさであった10年前に存在したこのWebコンテンツの1つの機能を保持しましょう。 。ブラウザはシンクライアントです。もしそうなら、貧弱なクライアントです。ブラウザには情報がありません。全ページリロードルール。 »view«は毎回新しく生成されます。

このWebのやり方は、大流行しているにもかかわらず、デスクトップと比べるとひどく後退していたことを思い出してください。あなたがそうするなら、デスクトップアプリはファットクライアント、またはリッチクライアントです。 (Microsoft Wordのようなプログラムでさえ、ある種のクライアント、文書のクライアントと考えることができます。)彼らは、情報に溢れ、データに関する知識に溢れたクライアントです。彼らはステートフルです。処理しているデータをメモリにキャッシュします。全ページのリロードのようながらくたはありません。

そして、このデスクトップの豊かなやり方は、おそらく2番目の頭字語、MVVMが生まれたところです。 Cの省略による、文字にだまされてはいけません。コントローラーはまだ存在します。彼らはする必要があります。何も削除されません。ステートフルネス、クライアントにキャッシュされたデータ(およびそのデータを処理するためのインテリジェンス)という1つの要素を追加します。そのデータ、本質的にクライアント上のキャッシュは、現在»ViewModel«と呼ばれます。それが豊かな双方向性を可能にするのです。以上です。

  • MVC =モデル、コントローラー、ビュー=基本的に一方向の通信=対話性が低い
  • MVVM =モデル、コントローラー、キャッシュ、ビュー=双方向通信=豊富な対話性

Flash、Silverlight、そして - そして最も重要な - JavaScriptで、WebはMVVMを取り入れていることがわかります。ブラウザを合法的にシンクライアントと呼ぶことはできなくなりました。プログラマビリティを見てください。彼らのメモリ消費量を見てください。現代のWebページ上のすべてのJavascript対話性を見てください。

個人的には、この理論と頭字語のビジネスが具体的な現実で言及しているものを見れば理解しやすいと思います。抽象的な概念は、特に具体的な問題についての説明に役立つ場合に役立ちます。そのため、理解が一巡する可能性があります。

244
Lumi

_ mvvm _ Model-View ViewModel はMVCに似ています、 Model-View Controller

コントローラ ViewModel に置き換えられます。 ViewModelはUIレイヤーの下にあります。 ViewModelは、ビューに必要なデータオブジェクトとコマンドオブジェクトを公開します。これは、ビューがデータとアクションを取得するために使用するコンテナオブジェクトと考えることができます。 ViewModelはモデルからデータを取得します。

Russel Eastはもっと詳しく議論しているブログをしています なぜMVVMはMVCと違うのですか

173
TStamper

1つには、MVVMはXAMLを使用して表示を処理するMVCパターンの発展形です。 この記事 は2つの側面のいくつかを概説しています。

Model/View/ViewModelアーキテクチャーの主な目的は、データ( "Model")の上に、データの概念をより厳密にマッピングする別の非視覚的コンポーネントの層( "ViewModel")があることです。データのビューの概念(「ビュー」)へ。モデルではなく、ビューがバインドするのはViewModelです。

88
Chris Ballance

Windows環境ではMVVMパターンの 説明を参照 することができます。

Model-View-ViewModelデザインパターンでは、アプリは3つの一般的なコンポーネントで構成されています。 enter image description here

  • Model :これはあなたのアプリが消費するデータモデルを表します。たとえば、写真共有アプリでは、このレイヤーはデバイスで利用可能な写真のセットと、写真ライブラリの読み書きに使用されるAPIを表します。

  • 表示 :通常、アプリは複数ページのUIで構成されています。ユーザーに表示される各ページは、MVVM用語のビューです。ビューは、ユーザーに表示されるものを定義およびスタイル設定するために使用されるXAMLコードです。モデルのデータはユーザーに表示されます。ビューモデルの仕事は、アプリの現在の状態に基づいてこのデータをUIに提供することです。たとえば、写真共有アプリでは、ビューはユーザーにデバイス上のアルバムのリスト、アルバム内の写真、およびおそらくユーザーに特定の写真を表示するUIを表示するUIになります。

  • ViewModel :ViewModelはデータモデル、または単にモデルをアプリのUIまたはビューに結び付けます。モデルからデータを管理するためのロジックを含み、XAML UIまたはビューがバインドできる一連のプロパティとしてデータを公開します。たとえば、写真共有アプリでは、ViewModelはアルバムのリストを公開し、アルバムごとに写真のリストを公開します。 UIは、写真がどこから来るのか、そしてどのように取得されるのかを認識しません。それは単にViewModelによって公開されるような写真のセットを知っていて、それらをユーザーに見せます。

48
Mat

主な違いの1つは、MVCでは、VがMを直接読み取り、Cを介してデータを操作するのに対して、MVVMでは、VMがMプロキシとして機能することです。利用可能な機能をあなたに提供する.

ジャンクでいっぱいでなければ、あなたのVMが単なるMプロキシで、Cがすべての機能を提供しているハイブリッドを誰も作成していないことに驚きます。

41
George R

簡単な違い:(YaakovのCoursera AngularJSコースに着想を得た)

enter image description here

_ mvc _ (モデルビューコントローラ)

  1. モデル: モデルにはデータ情報が含まれています。 Controller and Viewを呼び出したり使用したりしません。ビジネスロジックとデータを表す方法が含まれています。このデータの一部は、何らかの形でビューに表示されることがあります。また、データを何らかのソースから取得するためのロジックを含めることもできます。
  2. Controller: ビューとモデル間の接続として機能します。 ViewはControllerを呼び出し、Controllerはモデルを呼び出します。それは基本的にモデルやビューに適宜変更するように通知します。
  3. 表示: UIパーツとの取引。ユーザーと対話します。

_ mvvm _ (モデルビュービューモデル)

ViewModel

  1. それはビューの状態の表現です。
  2. ビューに表示されているデータが含まれています。
  3. 表示イベント、別名プレゼンテーションロジックに応答します。
  4. ビジネスロジック処理のために他の機能を呼び出します。
  5. 何も表示するようにビューに直接要求しないでください。
20
Pritam Banerjee

MVVMは プレゼンテーションモデル パターンの改良版(討論可能)です。唯一の違いは、WPFがデータバインディングとコマンド処理を実行する機能を提供する方法にあることだけです。

18
wekempf

MVCは制御された環境であり、MVVMは反応的な環境です。

制御された環境では、少ないコードと一般的なロジックのソースを持つべきです。これは常にコントローラ内に存在するはずです。しかしながら; Webの世界では、MVCはビュー作成ロジックとビュー動的ロジックに簡単に分けられます。創造はサーバ上にあり、動的なものはクライアント上にあります。これは、ASP.NET MVCとAngularJSの組み合わせでよく見られますが、サーバーはビューを作成してモデルを渡し、それをクライアントに送信します。その後、クライアントはViewと対話します。その場合、AngularJSはローカルコントローラとして介入します。モデルを送信すると、新しいモデルがサーバーコントローラーに渡されて処理されます。 (したがって、ソケットやAJAX etcを扱うときには、このサイクルが続き、この処理の他の多くの翻訳がありますが、アーキテクチャ全体については同じです。)

MVVMはリアクティブ環境であり、通常は何らかのイベントに基づいてアクティブになるコード(トリガーなど)を作成します。 MVVMが成功するXAMLでは、これはすべてのプログラミング言語を使用して任意のViewの任意のシステムで機能することになりますが、組み込みのデータバインディングフレームワークBUTを使用してすべて簡単に行えます。 MS固有のものではありません。 ViewModelが発生し(通常はプロパティ変更イベント)、Viewは作成したトリガーに基づいてそれに反応します。これは技術的になる可能性がありますが、肝心なのはビューがステートレスでロジックがないことです。値に基づいて状態を変更するだけです。さらに、ViewModelは非常に少ないロジックでステートレスであり、Modelsは状態を維持するだけなので基本的にゼロのロジックを持つStateです。これをアプリケーション状態(Model)、状態変換機能(ViewModel)、そしてビジュアル状態/インタラクション(View)として説明します。

MVCデスクトップまたはクライアント側のアプリケーションでは、モデルがあり、そのモデルはコントローラーによって使用されるべきです。モデルに基づいて、コントローラはビ​​ューを変更します。通常、ビューはインターフェイスを持つコントローラに関連付けられているため、コントローラはさまざまなビューと連携できます。 ASP.NETでは、コントローラーがモデルを管理し、選択したビューにモデルを渡すため、MVCのロジックはサーバー上で少し後退しています。その後、ビューはモデルに基づいたデータで埋められ、独自のロジックを持ちます(通常AngularJSで行われるような別のMVCセット)。人々はこれをアプリケーションMVCと議論して混乱させ、その両方をやろうとしますが、その時点でプロジェクトを維持することは最終的には災害になるでしょう。 MVCを使用するときは、必ずロジックとコントロールを1か所にまとめてください。 ControllerまたはModelデータに対応するために、Viewの背後にあるコード(またはWeb用のJS経由のView)にViewロジックを記述しないでください。コントローラーにビューを変更させます。ビュー内に存在すべき唯一のロジックは、使用しているインターフェースを介して作成および実行するために必要なものすべてです。この一例は、ユーザー名とパスワードの送信です。デスクトップまたはWebページ(クライアント上)のどちらが、ViewがSubmitアクションを起動するたびに送信プロセスを処理する必要があります。正しく行われていれば、いつでも簡単にMVC Webまたはローカルアプリの周りにあなたの方法を見つけることができます。

それは完全に反応的であるとしてMVVMは個人的に私のお気に入りです。モデルの状態が変わると、ViewModelはその状態を監視して変換します。 ViewはViewModelの状態変化を監視しており、ViewModelからの変換に基づいて更新されます。純粋なMVVMと呼ぶ人もいますが、実際には1つしかありませんし、どのように主張しても構いません。ビューに論理がまったく含まれていない純粋なMVVMです。

これはちょっとした例です:ボタンを押したときにメニューをスライドさせたいとしましょう。 MVCでは、あなたのインターフェースにMenuPressedアクションがあります。 MenuボタンをクリックしたときにControllerはそれを認識し、次にSlideMenuInなどの別のInterfaceメソッドに基づいてViewをMenu内でスライドするように指示します。何のための往復?コントローラーがあなたができない、または何か他のことをしたくないと決心した代わりにそれが理由です。コントローラーがそうでない限り、コントローラーはビューを担当し、ビューは何もしません。しかしながら; MVVMでは、アニメーションのスライドメニューは組み込みで一般的なものでなければならず、スライドインするように指示されるのではなく、何らかの値に基づいてスライドメニューが表示されます。そのため、ViewModelを監視し、ViewModelが言うと、IsMenuActive = true(またはその代わり)のアニメーションが実行されます。さて、それで私はもう一つのポイントを本当に明確にし、注意を払うことを望みます。 IsMenuActiveはおそらく悪いMVVMかViewModelデザインです。 ViewModelを設計するときは、Viewが機能をまったく持っていないことを想定して、変換されたモデル状態を渡すだけではいけません。そのようにして、メニューを削除してデータ/オプションを別の方法で表示するようにビューを変更することにした場合、ViewModelは関係ありません。では、メニューをどのように管理しますか?データが理にかなっているとき、それはその方法です。したがって、これを行う1つの方法は、Menuにオプションのリスト(おそらく内側のViewModelの配列)を指定することです。そのリストがデータを持っているならば、メニューはそれからトリガーを通して開くことを知っています、そうでなければそれはトリガーを通して隠すことを知っています。あなたは単にメニューのデータを持っているか、ViewModelにはありません。 ViewModelでそのデータを表示/非表示にすることを決定しないでください。単にモデルの状態を変換するだけです。このように、ビューは完全に反応的で一般的であり、さまざまな状況で使用できます。

あなたがそれぞれのアーキテクチャーに少なくとも少し慣れておらず、ネット上でALOT OF BAD情報を見つけるのでそれを学ぶことは非常に混乱する可能性があるのであれば、これらすべてのことはおそらく全く意味をなさないでしょう。

そう…これを正しくするために心に留めておくべきこと。アプリケーションの設計方法とそれに対するSTICKを事前に決定します。

あなたがMVCをするならば、それは素晴らしいです、そしてあなたのControllerが管理可能で、あなたのViewを完全にコントロールしていることを確認してください。大きなビューがある場合は、異なるコントローラを持つコントロールをビューに追加することを検討してください。それらのコントローラを異なるコントローラにカスケード接続しないでください。維持することは非常にイライラする。少し時間をかけて、別々のコンポーネントとして機能するように、ものを別々に設計してください。そして、常にコントローラーにモデルにストレージをコミットまたは永続化するように指示させます。 MVC inの理想的な依存関係の設定は表示←コントローラ→モデルまたはASP.NET(始めません)モデル←表示↔コントローラ→モデル(モデルは同じでもまったく違うものでもかまいません) ControllerからViewへのモデル) ...もちろん、この時点でView内のControllerを知る必要があるのは、ほとんどの場合エンドポイント参照でModelを渡す場所を知るためです。

あなたがMVVMをするなら、私はあなたの親切な魂を祝福します、しかしそれを正しくするために時間をかけてください!一方にはインターフェースを使用しないでください。値に基づいて表示方法を決定します。 View with Mock dataで遊んでください。あなたがその時にそれを望んでいなかったにもかかわらずあなたがあなたにあなたにメニューを表示しているビューを持っているなら(例に従って)それで良い。あなたの見解はそれが期待通りに働いていて、それがそうであるように値に基づいて反応しています。 ViewModelが特定の変換された状態にあるときにこれが起こらないようにするために、トリガーにさらにいくつかの要件を追加するか、ViewModelにこの状態を空にするように指示してください。あなたのViewModelでは、Viewがそれを見るべきかどうかをそこから決めているかのように、内部ロジックでこれを削除しないでください。メニューがあるかViewModelにないと仮定できないことを忘れないでください。そして最後に、モデルはあなたが変更することを可能にするべきであり、そして最も可能性が高いのはストア状態です。これが検証とすべてが行われる場所です。たとえば、モデルが状態を変更できない場合、それは単に自分自身をダーティーか何かとしてフラグを立てます。 ViewModelがこれを認識すると、何が汚れているのかを変換し、Viewはこれを認識して別のトリガーを介して情報を表示します。 View内のすべてのデータをViewModelにバインドすることができるため、すべてをModelのみに動的にすることができます。ViewModelは、Viewがバインディングにどのように反応するかについてはまったくわかりません。実際のところ、モデルはViewModelを認識していません。依存関係を設定するとき、それらはそのように、そしてそのようにだけ指し示すべきですView→ViewModel→ModelモデルにVIEWを渡すビューにはモデル期間が表示されないようにする必要があります。

これが私の最後の秘訣です。うまく設計されているが非常に単純なMVCアプリケーションを見て、MVVMアプリケーションについても同じことをしてください。一方は柔軟性がゼロに制限された状態でより多くのコントロールを持ち、もう一方は柔軟性を持たず無限の柔軟性を持ちます。

制御された環境は、一連のコントローラまたは(単一のソース)からアプリケーション全体を管理するのに適していますが、リアクティブ環境は、残りのアプリケーションが何をしているのかまったくわからないまま別々のリポジトリに分割できます。マイクロ管理と無料管理。

私があなたを混乱させていないのであれば、私に連絡してみてください。

結局のところ、私たちはみんなプログラマーであり、その無秩序はコーディングの中で私たちの中に住んでいるのです。プロジェクトや大規模チームでは、デザインパターンについて合意し、それを実施することが本当に役立ちます。ある日それは初めに取られる小さい余分ステップが後に貯蓄の飛躍的な限界になるようにするでしょう。

16

Viewmodelはあなたのユーザーインターフェース要素のための「抽象」モデルです。ビュー内でコマンドやアクションを非視覚的な方法で実行できるようにする必要があります(たとえばテストするため)。

MVCを使用したことがある場合は、ビューの状態を反映するためにモデルオブジェクトを作成すると便利な場合があります。たとえば、編集ダイアログなどを表示したり非表示にしたりします。

MVVMパターンは、単純にすべてのUI要素に対するそのプラクティスの一般化です。

そしてそれはMicrosoftのパターンではない、それに付け加えるものはWPF/Silverlightデータバインディングがこのパターンを扱うのに特に適しているということである。しかし、例えばJavaサーバーの面でそれを使用するのを止めるものは何もありません。

14
DaniCE

MVCを使用して強く型付けされたViewModelをビューに挿入する

  1. コントローラーは、ViewModelを更新し、それをViewに注入する役割を果たします。 (取得リクエスト用)
  2. ViewModelは、最後に選択されたアイテムなどのDataContextおよびビューステートのコンテナです。
  3. モデルにはDBエンティティが含まれており、クエリとフィルタリングを行うDBスキーマに非常に近いです。 (私はこれのためにEFとLINQが好きです)
  4. また、モデルはリポジトリおよび/または結果の強力な型への投影を考慮する必要があります(EFには、クエリを注入して強力に戻すための直接ADOアクセスのための優れたメソッドEF.Database.Select(querystring、parms)がありますタイプ:これはEFがスロー引数であることを解決しますEFはスローではありません
  5. ViewModelはデータを取得し、ビジネスルールと検証を行います
  6. post backのコントローラーは、ViewModel Postメソッドを計算し、結果を待ちます。
  7. コントローラーは、新しく更新されたViewmodelをViewに注入します。ビューは強力な型バインディングのみを使用します。
  8. ビューは単にデータをレンダリングし、イベントをコントローラーにポストバックするだけです。 (以下の例を参照)
  9. MVCはインバウンド要求をインターセプトし、strong data typeで適切なコントローラーにルーティングします

このモデルでは、MSFTのMVCマシンがそれを隠しているため、要求または応答オブジェクトとのHTTPレベルの接触はありません。

上記の項目6の説明(要求による)...

次のようなViewModelを想定します。

public class myViewModel{
     public string SelectedValue {get;set;}
public void Post(){
    //due to MVC model binding the SelectedValue string above will be set by MVC model binding on post back.
    //this allows you to do something with it.
    DoSomeThingWith(SelectedValue);
    SelectedValue = "Thanks for update!";
 }
}

投稿のコントローラーメソッドは次のようになります(以下を参照)。MVCのインスタンスは、MVCバインディングメカニズムによって自動的にインスタンス化されることに注意してください。その結果、クエリ文字列レイヤーにドロップダウンする必要はありません!これは、クエリ文字列に基づいてViewModelをインスタンス化するMVCです!

[HTTPPOST]   
public ActionResult MyPostBackMethod (myViewModel mvm){
         if (ModelState.IsValid)
        {
               // Immediately call the only method needed in VM...
               mvm.Post()
        }
      return View(mvm);
}

上記のこのactionmethodが意図したとおりに機能するためには、投稿で返されないものを初期化するnull CTORを定義する必要があることに注意してください。ポストバックは、変更されたものの名前/値のペアもポストバックする必要があります。名前/値のペアが欠落している場合、MVCバインディングエンジンは適切な処理を実行しますが、これは単に何も行いません!これが発生した場合、「ポストバックでデータを失っています」と言うことに気付くかもしれません...

このパターンの利点は、ViewModelがすべての「クラッター」作業をModel/Buisnessロジックに接続することであり、コントローラーは単なる種類のルーターにすぎないことです。動作中のSOCです。

9
John Peters

私が言えることから、MVVMはMVCのMVにマッピングします。つまり、従来のMVCパターンでは、VはMと直接通信しません。MVの第2バージョンでは、MとVの間に直接リンクがあります。実際には、MVVMでは完全には説明されていない、より広い範囲のアプリケーションワークフロー(または使用シナリオの実装)が残っています。これがコントローラの役割です。これらの下位レベルの要素をコントローラから削除することで、これらの要素はよりクリーンになり、アプリケーションの使用シナリオやビジネスロジックの変更が容易になり、コントローラの再利用性も高まります。

9
se_thoughts

他の答えは、アーキテクチャパターンの主題にあまり詳しくない人にとっては理解しにくいかもしれません。アプリアーキテクチャを初めて使用する人は、その選択が実際にアプリにどのように影響するか、コミュニティでの大騒ぎが何であるかを知りたいかもしれません。

上記にいくらか光を当てようとして、MVVM、MVP、MVCを含むこの脚本を作りました。ストーリーは、ユーザーが映画検索アプリの[検索]ボタンをクリックすることで始まります:

ユーザー:クリック…

表示:誰ですか? [MVVM | MVP | MVC]

ユーザー:検索ボタンをクリックしました…

View:OK、ちょっと待って…。 [MVVM | MVP | MVC]

ViewViewModel|Presenter|Controllerを呼び出す… )[MVVM | MVP | MVC]

View:ちょっとViewModel|Presenter|Controller、aユーザーが検索ボタンをクリックしたばかりですが、どうすればよいですか? [MVVM | MVP | MVC]

ViewModel|Presenter|Controller:ちょっとViewはそのページに検索用語はありますか? [MVVM | MVP | MVC]

View:はい、ここでは…「ピアノ」[MVVM | MVP | MVC]

-これはMVVMMVP | MVC ———の最も重要な違いです

Presenter:ありがとうView、…一方、Modelで検索語を検索しています。進捗バーを表示[MVP | MVC]

Presenter|ControllerModel…を呼び出しています)[MVP = | MVC]

ViewController:ありがとう、Modelで検索語を検索しますが、直接更新はしません。代わりに、結果があればsearchSearchsListObservableのイベントをトリガーします。だから、それを観察したほうがいい。 [MVVM]

(searchResultsListObservableのトリガーを監視している間、ViewModelは通信しないため、Viewはユーザーに何らかの進捗バーを表示する必要があると考えますそれ)

——————————————————————————————

ViewModel|Presenter|Controller:ちょっとModel、Doこの検索用語に一致するものがありますか?:“ piano” [MVVM | MVP | MVC]

Model:HeyViewModel|Presenter|Controller、let me check…[MVVM | MVP | MVC]

Modelは映画データベースへのクエリを作成しています...)[MVVM | MVP | MVC]

( しばらくして … )

————これはMVVMMVPMVCの間の分岐点です————–

Model:リストを見つけました、ViewModel|Presenter、ここはJSON“ [ {「名前」:「ピアノ教師」、「年」:2001}、{「名前」:「ピアノ」、「年」:1993}]” [MVVM | MVP]

Model:使用可能な結果があります、コントローラー。インスタンスにフィールド変数を作成し、結果を入力しました。名前は「searchResultsList」です[MVC]

Presenter|ControllerthanksModelに戻り、View)[MVP | MVC]

Presenter:お待ちいただきありがとうございますView、一致する結果のリストを見つけて、表示可能な形式で整理しました:[“ Piano Teacher 2001″ 、「ピアノ1993」]]。また、進行状況バーを非表示にしてください[MVP]

Controller:お待ちいただきありがとうございますView、Modelに検索クエリについて質問しました。一致する結果のリストを見つけて、そのインスタンス内の「searchResultsList」という名前の変数に保存したという。そこから入手できます。また、進行状況バーを非表示にしてください[MVC]

ViewModel:searchResultsListObservableのオブザーバーは、表示可能な形式のこの新しいリストがあることを通知されます:[“ Piano Teacher 2001″、” Piano 1993”]。[MVVM]

View:ありがとうございます。プレゼンター[MVP]

View:ありがとう「Controller」[MVC](Now theView自身に疑問を呈しています:Modelから得られた結果をユーザーにどのように提示すればよいですか?映画の制作年は最初に来るべきですか、それとも最後に来るべきですか...?)

View:ああ、searchResultsListObservableに新しいトリガーがあります…、良い、表示可能なリストがあります。今はリストに表示するだけです。結果が得られたら、進行状況バーも非表示にする必要があります。 [MVVM]

興味のある方のために、ムービー検索Androidアプリを実装してMVVM、MVP、MVCを比較する一連の記事 here を作成しました。

9
Ali Nem

MVVMはビューモデルをミックスに追加します。通常のモデルにUI固有の部分をすべて追加することなく、WPFの多くのバインディングアプローチを使用できるため、これは重要です。

私は間違っているかもしれませんが、MVVMが本当にコントローラを混ぜ合わせるかどうかはわかりません。私はその概念がより一致していると思います: http://martinfowler.com/eaaDev/PresentationModel.html 。私は、それがパターンに組み込まれているのではなく、MVCと組み合わせることを選ぶと思います。

9
eglasius

MVVMの Origin に言及せずにこれが非常に投票された答えであることは私を驚かせます。 _ mvvm _ は、Microsoftコミュニティで使用されている一般的な用語で、Martin Fowlerの Presentation Model からの 由来 です。そのため、パターンの動機や他の人との違いを理解するためには、パターンについての最初の記事が最初に読むことです。

9
Cheng

一般的に、MVCはWeb開発で使用され、MVVMはWPF/Silverlight開発で最も一般的です。ただし、WebアーキテクトがMVCとMVVMを混在させることがあります。

たとえば、 knockout.js を使用すると、クライアント側にMVVMが使用されます。そしてあなたのMVCのサーバーサイドも変わることができます。複雑なアプリでは、誰も純粋なモデルを使用しません。 ViewCodelをMVCの「モデル」として使用することは意味があり、実際のモデルは基本的にこのVMの一部になります。これはあなたに余分な抽象化層を与えます。

6

ViewModelはControllerとはまったく異なる機能を持っているため、ControllerはMVVMのViewModelに置き換えられません。あなたのモデル、ViewModel、Viewはコントローラがなくても大したことはしないので、あなたはまだコントローラが必要です。

MVVMCは私の控え目な意見では正しい名前です。

ご覧のとおり、ViewModelはMVCパターンに追加されたものです。変換ロジック(オブジェクトを文字列に変換するなど)をControllerからViewModelに移動します。

4
Ini

MVVMC、あるいはおそらくMVC +は、迅速なアプリケーション開発と同様に企業にとっても実行可能なアプローチであるように思われます。 UIをビジネスロジックやインタラクションロジックから切り離すのはいいことですが、「純粋な」MVVMパターンと利用可能なほとんどの例は、単一のビューで最も効果的に機能します。

あなたのデザインについてはわかりませんが、私のアプリケーションのほとんどはページといくつかの(再利用可能な)ビューを含んでいるので、ViewModelはある程度対話する必要があります。ページをコントローラとして使用すると、MVVMの目的が完全に無効になります。そのため、基盤となるロジックに "VM-C"アプローチを使用しないと、アプリケーションの成熟に伴って構造が困難になる場合があります。 VB-6でも、たいていの場合、ビジネスロジックをButtonイベントにコーディングするのをやめて、コマンドをコントローラに「中継」し始めました。私は最近、そのトピックに関する多くの新しいフレームワークを調べました。私のお気に入りは明らかにMagellan(at codeplex)アプローチです。ハッピーコーディング!

http://en.wikipedia.org/wiki/Model_View_ViewModel#References

4
der Martin

実用的な観点から、MVC(Model-View-Controller)はパターンです。しかし、MVCをASP.net MVCとして使用する場合、Entity Framework(EF)および「強力なツール」と組み合わせると、データベース、テーブル、および列をWebページに移動するための非常に強力で部分的に自動化されたアプローチCRUD操作またはR(検索または読み取り)操作のみ。少なくとも私がMVVMを使用していたとき、View Modelsはビジネスオブジェクトに依存するモデルと相互作用し、それらは順番に「手作り」され、EFが提供するのと同じくらい優れたモデルを手に入れました。ボックス "#:。実用的なプログラミングの観点からすると、MVCはすぐに使えるユーティリティを1つ提供するので、良い選択と思われますが、それでもまだ追加の可能性があります。

2
JosephDoggie

与えられた回答の多くを補完するものとして、私はModernクライアントサイドWebまたは リッチWebアプリケーション の観点からいくつかの観点を追加したいと思いました。

実際、最近では、単純なWebサイトや大規模なWebアプリケーションは、一般的にBootstrapなどの多くの一般的なライブラリで構築されています。 Steve Sandersonによって構築された Knockout は、パターン内で最も重要な動作の1つを模したMVVMパターンのサポートを提供します。それは、View Modelによるデータバインディングです。少しのJavaScriptで、 Bootstrap の多くの機能を使用するのと同じように、単純なdata-bind HTML属性を持つページ要素に追加できるデータとロジックを実装することができます。これら2つのライブラリだけでインタラクティブコンテンツを提供します。ルーティングと組み合わせると、 シングルページアプリケーション を構築するためのシンプルでありながら強力なアプローチが得られます。

同様に、 Angular などのモダンなクライアントサイドフレームワークは、慣例に従ってMVCパターンに従いますが、サービスも追加します。興味深いことに、それはModel-View-Whatever(MVW)として宣伝されています。 ( スタックオーバーフローのこの記事 を参照。)

さらに、Angular 2のようなProgressive Webフレームワークの登場により、用語の変更や、コンポーネントがビューまたはテンプレートで構成されて相互作用する新しいアーキテクチャパターンが見られるようになりました。サービス - そのすべてをモジュールに含めることができます。そして一連のモジュールがアプリケーションを構成します。

2

私はMVCとMVVMが同じであると以前考えていました。今フラックスの存在のために私は違いを言うことができます:

MVCでは、アプリの各ビューにはモデルとコントローラがあるので、ビュー、モデル、ビューコントローラと呼びます。このパターンは、あるビューが別のビューとどのように通信できるかを教えてくれるわけではありません。したがって、異なるフレームワークでは、それに対する実装が異なります。たとえば、コントローラが互いに通信する実装がありますが、他の実装ではそれらを仲介する別のコンポーネントがあります。ビューモデルが互いに通信する実装もあります。これは、ビューモデルはビューコントローラによってのみアクセスされるべきであるため、MVCパターンの中断です。

MVVMでは、各コンポーネントのビューモデルもあります。このパターンは、ビューがどのようにビューモデルに影響を与えるかを指定しないため、通常、ほとんどのフレームワークは単にビューモデルにコントローラの機能を含めます。しかし、MVVMはあなたのビューモデルのデータがモデルから来るべきであるとあなたに伝えます、それは気付かないか特定のビューにカスタムではないモデル全体です。

違いを説明するために、フラックスパターンを取りましょう。フラックスパターンは、アプリ内のさまざまなビューが通信する方法を示します。各ビューはストアをリッスンし、ディスパッチャを使用してアクションを起動します。ディスパッチャは今度は、行ったばかりのアクションについてすべてのストアに通知し、ストアは自分自身を更新します。 FluxのストアはMVVMの(一般的な)モデルに対応します。それは特定の見方に慣れているわけではありません。そのため、通常ReactとFluxを使うとき、各Reactコンポーネントは実際にMVVMパターンを実装します。アクションが発生すると、ビューモデルはディスパッチャを呼び出し、最後にモデルであるストア内の変更に従って更新されます。 MVCではビューモデルを更新できるのはコントローラだけなので、各コンポーネントがMVCを実装しているとは言えません。 MVVMはFluxと一緒に動作することができます(MVVMはビューとビューモデル間の通信を処理し、Fluxは異なるビュー間の通信を処理します)が、MVCはFluxを主要な原則を破ることなく処理できません。

2
Alon

web開発では、mvcはサーバー側、mvvmはクライアント側(ブラウザ)です。

ほとんどの場合、JavaScriptはブラウザのmvvmに使用されます。 mvcには多くのサーバーサイド技術があります。

1
Maulik Gangani

非常に短い-MVC Controlerではビューを(コントロール)認識しますが、MVVMではViewModelは誰がビューを消費するかを認識しません。 ViewModelは、観察可能なプロパティとアクションを、それを使用することに興味がある人に公開します。 ViewModel内にはUIへの参照がないため、この事実によりテストが容易になります。

1
daneejela

今日、MVCは利他的な開発者に有利ではなく、眉をひそめています。

Viper、React、MVVM、これらは優れていますが、MVCは悪くてくだらない…

真実か神話か

まあ、MVCは確かに古く、最も一般的なものである恐れのある「大規模なビューコントローラー」という欠陥を確実に持っています。

ただし、前述の新しいアーキテクチャはMVC固有の問題の解決策をいくつか表に示していますが、いくつかの欠点もあります。

MVCは素晴らしいです。プログラマーは不注意です。

1
Helen Wood