web-dev-qa-db-fra.com

Quelle est la différence entre MVC et MVVM?

Existe-t-il une différence entre le modèle standard "Model View Controller" et le modèle Microsoft/Model/View/ViewModel?

1248
Bjorn Reppen

MVC/MVVM n'est pas un choix /ou .

Les deux modèles apparaissent de différentes manières, dans les développements ASP.Net et Silverlight/WPF.

Pour ASP.Net, MVVM est utilisé pour une liaison bidirectionnelle des données dans les vues. Il s’agit généralement d’une implémentation côté client (par exemple, avec Knockout.js). En revanche, MVC permet de séparer les problèmes côté serveur .

Pour Silverlight et WPF, le modèle MVVM est plus complet et peut apparaître pour remplacer MVC (ou d’autres modèles d’organisation du logiciel en responsabilités distinctes). . Une hypothèse, qui sortait souvent de ce modèle, était que la ViewModel remplaçait simplement le contrôleur dans MVC (comme si vous pouviez simplement remplacer VM par C dans l'acronyme. et tout serait pardonné) ...

Le ViewModel ne remplace pas nécessairement le besoin de contrôleurs séparés.

Le problème est le suivant: pour être indépendamment testable *, et surtout réutilisable en cas de besoin, un modèle de vue n'a aucune idée de la vue qui l'affiche, mais plus important encore , aucune idée de l'origine de ses données .

* Remarque: en pratique, les contrôleurs suppriment la majeure partie de la logique du ViewModel qui nécessite des tests unitaires. La VM devient alors un conteneur muet qui nécessite peu de tests, voire aucun. C’est une bonne chose, car la VM n’est qu’un pont entre le concepteur et le codeur, elle doit donc rester simple.

Même dans MVVM, les contrôleurs contiennent généralement toute la logique de traitement et décident quelles données afficher dans quelles vues à l'aide de quels modèles de vue.

D'après ce que nous avons vu jusqu'à présent, le modèle ViewModel a pour principal avantage de supprimer le code de XAML code-behind et de rendre l'édition de XAML une tâche plus indépendante . Nous créons toujours des contrôleurs, au besoin, pour contrôler (sans jeu de mots) la logique globale de nos applications.

Les instructions de base de MVCVM que nous suivons sont les suivantes:

  • Les vues affichent une certaine forme de données . Ils n'ont aucune idée d'où proviennent les données.
  • Les ViewModels contiennent une certaine forme de données et de commandes , ils ne savent pas d'où proviennent les données, ni le code, ni leur affichage.
  • Les modèles contiennent les données réelles (diverses méthodes de contexte, de stockage ou autres)
  • Les contrôleurs écoutent et publient des événements. Les contrôleurs fournissent la logique qui contrôle quelles données sont vues et où. Les contrôleurs fournissent le code de commande au ViewModel afin qu'il soit réellement réutilisable.

Nous avons également constaté que la structure Sculpture code-gen implémentait MVVM et un modèle similaire à Prism ET utilisait également abondamment les contrôleurs pour séparer toute la logique de cas d’utilisation.

Ne supposez pas que les contrôleurs sont rendus obsolètes par View-models.

J'ai commencé un blog sur ce sujet que je vais ajouter au fur et à mesure que je peux . La combinaison de MVCVM avec les systèmes de navigation courants pose des problèmes, car la plupart des systèmes de navigation n'utilisent que des vues et des ordinateurs virtuels, mais nous y reviendrons dans des articles ultérieurs.

L’utilisation d’un modèle MVCVM présente un autre avantage: , seuls les objets de contrôleur doivent exister en mémoire pour la vie de l’application et les contrôleurs contiennent principalement du code et peu de données d'état (c'est-à-dire une surcharge de mémoire). Cela permet de réduire considérablement le volume d'applications nécessitant beaucoup de mémoire que les solutions dans lesquelles les modèles de vue doivent être conservés. Cet outil est idéal pour certains types de développement mobile (par exemple, Windows Mobile avec Silverlight/Prism/MEF). Cela dépend bien sûr du type d'application, car il se peut que vous deviez conserver les ordinateurs virtuels mis en cache de temps en temps pour plus de réactivité.

Remarque: ce message a été modifié à plusieurs reprises et ne vise pas spécifiquement la question étroite posée. J'ai donc mis à jour la première partie pour couvrir également cette question. Une grande partie de la discussion, dans les commentaires ci-dessous, concerne uniquement ASP.Net et non la vue d'ensemble. Ce message était destiné à couvrir l'utilisation plus large de MVVM dans Silverlight, WPF et ASP.Net et à décourager les utilisateurs de remplacer les contrôleurs par ViewModels.

659
Gone Coding

Je pense que la meilleure façon de comprendre ce que ces acronymes sont supposés signifier est de les oublier un instant. Pensez plutôt au logiciel à partir duquel ils ont été créés. Cela se résume vraiment à la différence entre le début du Web et le bureau.

Le premier acronyme, MVC, provient du Web. (Oui, cela existait peut-être auparavant, mais le Web est le moyen par lequel il a été vulgarisé auprès de la masse de développeurs Web.) Pensez à la base de données, aux pages HTML et au code intermédiaire. Affinons un peu cela pour arriver à MVC: Pour "base de données", supposons que la base de données plus le code d'interface. Pour les "pages HTML", supposons les modèles HTML plus le code de traitement des modèles. Pour "code inbetween", supposons que le code mappant les clics de l'utilisateur sur des actions, affectant éventuellement la base de données, provoque définitivement l'affichage d'une autre vue. C'est ça, au moins aux fins de cette comparaison.

Gardons une caractéristique de ce contenu Web, non pas ce qu’elle est aujourd’hui, mais telle qu’elle existait il ya dix ans, lorsque JavaScript était un ennui humble et ignoble que les vrais programmeurs faisaient bien d’éviter: La page HTML est essentiellement idiote et passive . Le navigateur est un client léger ou, si vous préférez, un client médiocre. Il n'y a pas d'intelligence dans le navigateur. Règle de rechargement de page complète. La "vue" est générée à chaque fois.

Rappelons-nous que cette méthode Web, bien que faisant fureur, était terriblement en retard par rapport au bureau. Les applications de bureau sont des clients lourds, ou des clients riches, si vous voulez. (Même un programme tel que Microsoft Word peut être considéré comme une sorte de client, un client pour des documents.) Ce sont des clients pleins de renseignements et de connaissances sur leurs données. Ils sont à l'état. Ils mettent en cache les données qu'ils gèrent en mémoire. Aucune merde comme un rechargement complet de la page.

Et ce mode de travail riche est probablement à l'origine du deuxième acronyme, MVVM. Ne vous laissez pas berner par les lettres, par l'omission du C. Les contrôleurs sont toujours là. Ils doivent être. Rien n'est enlevé. Nous ajoutons simplement une chose: l’état d’avancement, les données mises en cache sur le client (et l’intelligence permettant de gérer ces données). Ces données, essentiellement un cache sur le client, s'appellent maintenant "ViewModel". C'est ce qui permet une interactivité riche. Et c'est tout.

  • MVC = modèle, contrôleur, vue = communication essentiellement à sens unique = faible interactivité
  • MVVM = modèle, contrôleur, cache, vue = communication bidirectionnelle = interactivité étendue

Nous pouvons voir qu'avec Flash, Silverlight et, plus important encore, JavaScript, le Web a adopté MVVM. Les navigateurs ne peuvent plus être légitimement appelés clients légers. Regardez leur programmabilité. Regardez leur consommation de mémoire. Regardez toute l’interactivité Javascript sur les pages Web modernes.

Personnellement, je trouve cette théorie et cette affaire d’acronyme plus faciles à comprendre en regardant ce à quoi elle fait référence dans la réalité concrète. Les concepts abstraits sont utiles, en particulier quand ils sont démontrés sur un sujet concret. La compréhension peut donc tourner à toute vitesse.

256
Lumi

MVVM Modèle-View ViewModel est similaire à MVC, Modèle-View Controller

Le contrôleur est remplacé par un ViewModel . Le ViewModel est situé sous la couche d'interface utilisateur. ViewModel expose les objets de données et de commande dont la vue a besoin. Vous pourriez considérer cela comme un objet conteneur dont la vue va extraire ses données et ses actions. Le ViewModel extrait ses données du modèle.

Russel East fait un blog discutant plus en détail Pourquoi MVVM est différent de MVC

173
TStamper

D'une part, MVVM est une progression du modèle MVC qui utilise XAML pour gérer l'affichage. Cet article décrit certaines des facettes des deux.

L’architecture Modèle/Vue/ViewModel semble être axée sur le fait qu’en plus des données ("le modèle"), il existe une autre couche de composants non visuels ("le ViewModel") mappant plus étroitement les concepts des données. aux concepts de la vue des données ("la vue"). C’est le ViewModel auquel la vue se lie, pas le modèle directement.

88
Chris Ballance

Microsoft a fourni ne explication du modèle MVVM dans l'environnement Windows ici .

Voici une section cruciale:

Dans le modèle de conception Model-View-ViewModel, une application est composée de trois composants généraux. enter image description here

  • Modèle : Ceci représente le modèle de données consommé par votre application. Par exemple, dans une application de partage d'images, cette couche peut représenter l'ensemble des images disponibles sur un périphérique et l'API utilisée pour lire et écrire dans la bibliothèque d'images.

  • Affichage : une application est généralement composée de plusieurs pages d'interface utilisateur. Chaque page présentée à l'utilisateur est une vue dans la terminologie de MVVM. La vue est le code XAML utilisé pour définir et styliser ce que voit l'utilisateur. Les données du modèle sont affichées à l’utilisateur. C’est le travail du ViewModel de fournir à l’UI ces données en fonction de l’état actuel de l’application. Par exemple, dans une application de partage d'images, les vues seraient l'interface utilisateur qui montre à l'utilisateur la liste des albums du périphérique, les images d'un album et peut-être une autre qui montre à l'utilisateur une image particulière.

  • ViewModel : ViewModel lie le modèle de données, ou simplement le modèle, à l'interface utilisateur ou aux vues de l'application. Il contient la logique avec laquelle gérer les données du modèle et expose les données sous la forme d'un ensemble de propriétés auxquelles l'interface utilisateur XAML, ou les vues, peut se lier. Par exemple, dans une application de partage d'images, ViewModel afficherait une liste d'albums et, pour chaque album, une liste d'images. L'interface utilisateur ne sait pas d'où proviennent les images et comment elles sont récupérées. Il sait simplement qu'un ensemble d'images est exposé par ViewModel et les montre à l'utilisateur.

48
Mat

Je pensais que l’une des principales différences était que dans MVC, votre V lisait votre M directement et passait par le C pour manipuler les données, alors que dans MVVM, votre VM agissait comme un proxy M, ainsi que vous fournir les fonctionnalités disponibles V.

Si je ne suis pas plein de bric-à-brac, je suis surpris que personne n'ait créé un hybride, où votre VM est simplement un proxy M, et C fournit toutes les fonctionnalités.

42
George R

Simple Difference: (Inspiré du cours Coursera AngularJS de Yaakov)

enter image description here

MVC (Contrôleur de vue modèle)

  1. Modèles: Les modèles contiennent des informations de données. N'appelle ni n'utilise Controller et View. Contient la logique métier et les moyens de représenter les données. Certaines de ces données, sous une forme quelconque, peuvent être affichées dans la vue. Il peut également contenir une logique pour récupérer les données d'une source.
  2. Contrôleur: Agit en tant que connexion entre la vue et le modèle. Afficher les appels Controller and Controller appelle le modèle. Il informe essentiellement le modèle et/ou la vue à modifier, le cas échéant.
  3. Vue: Traite une partie de l'interface utilisateur. Interagir avec l'utilisateur.

MVVM (Model View View Model)

ViewModel :

  1. C'est la représentation de l'état de la vue.
  2. Il contient les données affichées dans la vue.
  3. Répond pour voir les événements, alias la logique de présentation.
  4. Appelle d'autres fonctionnalités pour le traitement de la logique métier.
  5. Ne demande jamais directement à la vue d'afficher quoi que ce soit.
21
Pritam Banerjee

MVC est un environnement contrôlé et MVVM est un environnement réactif.

Dans un environnement contrôlé, vous devriez avoir moins de code et une source de logique commune. qui devrait toujours vivre dans le contrôleur. Pourtant; dans le monde web, MVC est facilement divisé en logique de création de vues et logique dynamique de vues. La création vit sur le serveur et la vie dynamique sur le client. Vous le voyez souvent avec ASP.NET MVC combiné à AngularJS alors que le serveur crée une vue, transmet un modèle et l'envoie au client. Le client interagira ensuite avec la vue, auquel cas AngularJS entrera en tant que contrôleur local. Une fois soumis, le modèle ou un nouveau modèle est renvoyé au contrôleur de serveur et traité. (Ainsi, le cycle se poursuit et il existe de nombreuses autres traductions de cette manipulation lorsque vous travaillez avec des sockets ou AJAX etc., mais l'architecture est identique.)

MVVM est un environnement réactif, ce qui signifie que vous écrivez du code (tel que des déclencheurs) qui sera activé en fonction de certains événements. En XAML, où MVVM prospère, tout cela est facilement réalisable avec le framework de liaison de données intégré MAIS, comme mentionné, cela fonctionnera sur n’importe quel système de n'importe quelle vue avec n'importe quel langage de programmation. Ce n'est pas spécifique à MS. ViewModel se déclenche (généralement un événement de propriété modifiée) et la vue y réagit en fonction des déclencheurs que vous créez. Cela peut devenir technique, mais la ligne de fond est que la vue est sans état et sans logique. Il change simplement d'état en fonction des valeurs. De plus, les modèles ViewModels sont sans état avec très peu de logique et les modèles sont l’État avec une logique essentiellement nulle, car ils ne doivent conserver que l’état. Je décris ceci en tant qu'état d'application (modèle), en traducteur d'état (ViewModel), puis en état visuel/interaction (View).

Dans une application côté bureau ou client MVC, vous devez avoir un modèle, qui doit être utilisé par le contrôleur. En fonction du modèle, le contrôleur modifiera la vue. Les vues sont généralement liées à des contrôleurs avec des interfaces afin que le contrôleur puisse fonctionner avec une variété de vues. Dans ASP.NET, la logique de MVC est légèrement en arrière sur le serveur, car le contrôleur gère les modèles et les transmet à une vue sélectionnée. La vue est ensuite remplie avec des données basées sur le modèle et possède sa propre logique (généralement un autre ensemble MVC tel que réalisé avec AngularJS). Les gens vont discuter et obtenir cette confusion avec l'application MVC et essayer de faire les deux à un moment tel que maintenir le projet finira par devenir un désastre. TOUJOURS mettre la logique et le contrôle au même endroit lorsque vous utilisez MVC. N'écrivez PAS la logique de vue dans le code situé derrière la vue (ou dans la vue via JS pour le Web) pour prendre en charge les données de contrôleur ou de modèle. Laissez le contrôleur changer la vue. La SEULE logique qui doit vivre dans une vue est ce qu'il faut pour créer et exécuter via l'interface utilisée. Un exemple de ceci est la soumission d'un nom d'utilisateur et d'un mot de passe. Que ce soit le bureau ou la page Web (sur le client), le contrôleur doit gérer le processus de soumission chaque fois que la vue déclenche l'action de soumission. Si cela est fait correctement, vous pouvez toujours vous repérer facilement dans une application Web ou locale MVC.

MVVM est personnellement mon préféré car il est complètement réactif. Si un modèle change d'état, ViewModel écoute et traduit cet état et c'est tout !!! La vue écoute alors le ViewModel pour le changement d'état et il se met également à jour en fonction de la traduction du ViewModel. Certaines personnes appellent cela du MVVM pur, mais il n'y en a qu'un et je me fiche de la façon dont vous le discutez. C'est toujours un MVVM pur où la vue ne contient absolument aucune logique.

Voici un léger exemple: supposons que vous souhaitiez faire glisser un menu en appuyant sur un bouton. Dans MVC, vous aurez une action MenuPressed dans votre interface. Le contrôleur saura lorsque vous cliquerez sur le bouton Menu, puis demanderez à la vue de glisser dans le menu en fonction d'une autre méthode d'interface telle que SlideMenuIn. Un aller-retour pour quelle raison? Si le contrôleur décide que vous ne pouvez pas ou ne voulez pas faire autre chose, c'est pourquoi. Le contrôleur doit être en charge de la vue, la vue ne faisant rien sauf si le contrôleur le dit. POURTANT; dans MVVM, le menu de diapositives de l'animation doit être intégré et générique. Au lieu d'être invité à le faire, il sera basé sur une valeur. Donc, il écoute le ViewModel et quand ViewModel dit, IsMenuActive = true (ou cependant) l'animation qui a lieu. Maintenant, avec cela dit, je veux faire un autre point vraiment clair et s'il vous plaît prêter attention. IsMenuActive est probablement une conception BAD MVVM ou ViewModel. Lors de la conception d'un ViewModel, vous ne devez jamais présumer qu'une View aura des fonctionnalités, mais simplement transmettre l'état du modèle traduit. Ainsi, si vous décidez de modifier votre vue pour supprimer le menu et d'afficher simplement les données/options d'une autre manière, le modèle de vue ne s'en soucie pas. Alors, comment géreriez-vous le menu? Quand les données ont un sens, c'est comme ça. Donc, une façon de faire est de donner au menu une liste d’options (probablement un tableau de ViewModels internes). Si cette liste contient des données, le menu sait alors s’ouvrir via le déclencheur, sinon il sait se masquer via le déclencheur. Vous avez simplement des données pour le menu ou pas dans le ViewModel. NE décidez PAS d’afficher/cacher ces données dans le ViewModel. Traduisez simplement l’état du Modèle. De cette façon, la vue est complètement réactive et générique et peut être utilisée dans de nombreuses situations différentes.

Tout cela n'a probablement aucun sens si vous n'êtes pas déjà au moins légèrement familiarisé avec l'architecture de chacun et apprendre qu'il peut être très déroutant, car vous trouverez BEAUCOUP D'INFORMATIONS MAUVAISES sur le net.

Alors ... choses à garder à l'esprit pour bien faire les choses. Décidez dès le départ comment concevoir votre application et STICK TO IT.

Si vous utilisez MVC, ce qui est excellent, assurez-vous que votre contrôleur est gérable et contrôle parfaitement votre vue. Si vous avez une vue volumineuse, envisagez d’ajouter à celle-ci des contrôles dotés de contrôleurs différents. JUSTE NE PAS mettre en cascade ces contrôleurs vers différents contrôleurs. Très frustrant à maintenir. Prenez un moment et concevez les choses séparément de manière à fonctionner comme des composants séparés ... Et laissez toujours le contrôleur dire au modèle de valider ou de conserver le stockage. La configuration de dépendance idéale pour MVC dans est Affichage ← Contrôleur → Modèle ou avec ASP.NET (ne me démarrez pas) Modèle ← Affichage Contrôleur → Modèle (où Modèle peut être le Modèle identique ou totalement différent de Controller à View) ... bien sûr, le seul besoin de connaître Controller in View à ce stade est principalement la référence de point de terminaison pour savoir où revenir pour passer un modèle.

Si vous faites MVVM, je bénis votre âme bienveillante, mais prenez le temps de le faire DROITE! Ne pas utiliser les interfaces pour un. Laissez votre vue décider de son apparence en fonction des valeurs. Jouez avec les données View with Mock. Si vous vous retrouvez avec une vue qui vous montre un menu (comme dans l'exemple) alors que vous ne le vouliez pas à ce moment-là, BON. Votre avis fonctionne comme il se doit et réagit en fonction des valeurs comme il se doit. Ajoutez simplement quelques exigences supplémentaires à votre déclencheur pour vous assurer que cela ne se produit pas lorsque le ViewModel est dans un état traduit particulier ou que le ViewModel soit vidé pour vider cet état. Dans votre ViewModel, NE supprimez PAS cela avec une logique interne, comme si vous décidiez à partir de là si la vue devait la voir ou non. N'oubliez pas que vous ne pouvez pas supposer qu'il existe un menu ou non dans le ViewModel. Et enfin, le modèle devrait simplement vous permettre de changer et de stocker l’état le plus probable. C'est là que la validation et tout se produiront; Par exemple, si le modèle ne peut pas modifier l'état, il se signalera simplement comme étant sale ou quelque chose du genre. Lorsque le ViewModel réalise cela, il traduit ce qui est sale et la View le réalise et affiche des informations via un autre déclencheur. Toutes les données de la vue peuvent être liées au ViewModel. Ainsi, tout peut être dynamique uniquement dans le modèle. ViewModel n'a absolument aucune idée de la façon dont la vue réagira à la liaison. En fait, le modèle n'a aucune idée d'un ViewModel non plus. Lors de la configuration des dépendances, ils doivent pointer comme tel et seulement comme tel Affichage → ViewModel → Modèle (et une note de côté ici ... et cela sera probablement discuté aussi, mais je m'en fiche). Ne passez pas le modèle à la vue à moins que ce modèle ne soit immuable, sinon enveloppez-le avec un ViewModel approprié. La vue ne devrait pas voir une période de modèle. , c'est faux.)

Voici mon dernier conseil ... Regardez une application MVC bien conçue, mais très simple, et faites de même pour une application MVVM. L'un aura plus de contrôle avec une flexibilité limitée à zéro alors que l'autre n'aura aucun contrôle et une flexibilité illimitée.

Un environnement contrôlé permet de gérer l’ensemble de l’application à partir d’un ensemble de contrôleurs ou (une source unique), tandis qu’un environnement réactif peut être divisé en référentiels distincts sans aucune idée de ce que fait le reste de l’application. Micro gestion vs gestion libre.

Si je ne vous ai pas assez confus, essayez de me contacter ... Cela ne me dérange pas de revenir en détail sur cela avec des illustrations et des exemples.

En fin de compte, nous sommes tous des programmeurs et l'anarchie règne en codant ... Ainsi, les règles vont être brisées, les théories vont changer, et tout cela finira par se laver les porcs ... Mais quand on travaille sur de gros projets projets et sur de grandes équipes, il est vraiment utile de s’entendre sur un modèle de conception et de l’appliquer. Un jour, les petites mesures supplémentaires prises au début deviendront des pas de géant plus tard.

20
Michael Puckett II

MVVM est un raffinement (discutable) du modèle Presentation Model . Je dis discutable, car la seule différence réside dans la manière dont WPF offre la possibilité de faire la liaison de données et le traitement des commandes.

18
wekempf

Le modèle de vue est un modèle "abstrait" pour les éléments de votre interface utilisateur. Il doit vous permettre d'exécuter les commandes et les actions dans votre vue de manière non visuelle (par exemple, pour le tester).

Si vous avez déjà travaillé avec MVC, vous avez probablement déjà jugé utile de créer des objets de modèle reflétant l'état de votre vue, par exemple pour afficher et masquer une boîte de dialogue d'édition, etc. Dans ce cas, vous utilisez un modèle de vue.

Le modèle MVVM est simplement la généralisation de cette pratique à tous les éléments de l'interface utilisateur.

Et ce n’est pas un modèle Microsoft, mais les liaisons de données WPF/Silverlight sont particulièrement bien adaptées à l’utilisation de ce modèle. Mais rien ne vous empêche de l'utiliser avec Java faces du serveur, par exemple.

14
DaniCE

Injection de ViewModels fortement typés dans la vue à l'aide de MVC

  1. Le contrôleur est responsable de la création du ViewModel et de son injection dans la vue. (pour obtenir des demandes)
  2. ViewModel est le conteneur pour DataContext et l'état d'affichage tel que le dernier élément sélectionné, etc.
  3. Le modèle contient des entités de base de données et est très proche du schéma de base de données. Il effectue les requêtes et le filtrage. (J'aime EF et LINQ pour cela)
  4. Le modèle doit également prendre en compte les référentiels et/ou la projection des résultats dans des types forts (EF a une excellente méthode ... EF.Database.Select (chaîne de requête, paramètres) pour un accès direct ADO afin d'injecter des requêtes et de récupérer des types forts. Ceci adresse le paramètre EF est un argument lent. EF n'est pas lent!
  5. Le ViewModel récupère les données et effectue les règles métier et la validation.
  6. Le contrôleur sur post back appelle la méthode ViewModel Post et attend les résultats.
  7. Le contrôleur injectera le Viewmodel nouvellement mis à jour dans la vue. La vue utilise niquement la liaison de type fort.
  8. La vue restitue simplement les données et affiche les événements sur le contrôleur. (voir exemples ci-dessous)
  9. MVC intercepte la demande entrante et l'achemine vers le contrôleur approprié avec type de données fort

Dans ce modèle, il n'y a plus de niveau HTTP avec les objets de requête ou de réponse, car la machine MVC de MSFT nous le cache.

Pour clarifier le point 6 ci-dessus (sur demande) ...

Supposons un ViewModel comme ceci:

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!";
 }
}

La méthode du contrôleur de la publication ressemblera à ceci (voir ci-dessous), notez que l'instance de mvm est automatiquement instanciée par les mécanismes de liaison de MVC. En conséquence, vous ne devez jamais descendre dans la couche de chaîne de requête! MVC instancie ViewModel pour vous en fonction des chaînes de requête!

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

Notez que pour que cette méthode d'action ci-dessus fonctionne comme vous le souhaitez, vous devez avoir un CTOR null défini qui intialise les éléments qui ne sont pas renvoyés dans le message. La publication arrière doit également publier les paires nom/valeur pour les éléments qui ont changé. S'il manque des paires nom/valeur, le moteur de liaison MVC effectue la tâche appropriée, qui n'est tout simplement rien! Si cela se produit, vous risquez de vous retrouver en train de dire "Je perds des données sur les dos postés" ...

L'avantage de ce modèle réside dans le fait que ViewModel effectue tout le "fouillis" en s'interfaçant avec la logique Modèle/Affaires, le contrôleur étant simplement un routeur. C'est SOC en action.

9
John Peters

D'après ce que je peux dire, le MVVM correspond au MV de MVC - ce qui signifie que dans un motif MVC traditionnel, le V ne communique pas directement avec le M. Dans la deuxième version de MVC, il existe un lien direct entre M et V. MVVM semble prendre toutes les tâches liées aux communications M et V et les coupler pour les découpler du C. En fait, il existe toujours un flux de travail d'application à portée plus grande (ou la mise en œuvre des scénarios d'utilisation) qui n'est pas entièrement pris en compte dans MVVM. C'est le rôle du contrôleur. En supprimant ces aspects de niveau inférieur des contrôleurs, ils sont plus propres et facilitent la modification du scénario d'utilisation de l'application et de la logique métier, ce qui rend les contrôleurs plus réutilisables.

9
se_thoughts

Les autres réponses pourraient ne pas être faciles à comprendre pour quelqu'un qui ne connaît pas beaucoup le sujet des modèles architecturaux. Une personne novice dans l'architecture des applications voudra peut-être savoir comment son choix peut affecter son application dans la pratique et en quoi tout le monde parle dans les communautés.

En essayant de faire la lumière sur ce qui précède, j'ai composé ce scénario impliquant MVVM, MVP et MVC. L’histoire commence par un utilisateur qui clique sur le bouton "TROUVER" dans une application de recherche de film…:

Utilisateur: Cliquez…

View: Qui est-ce? [ MVVM | MVP | MVC ]

Utilisateur: je viens de cliquer sur le bouton de recherche…

Voir: Ok, attendez une seconde…. [ MVVM | MVP | MVC ]

(View appelant le ViewModel | Présentateur | Contrôleur…) [ MVVM | MVP | MVC ]

Voir: Hey ViewModel | Présentateur | Contrôleur, un utilisateur vient de cliquer sur le bouton de recherche, que dois-je faire? [ MVVM | MVP | MVC ]

ViewModel | Présentateur | Contrôleur: Hé View, y a-t-il un terme de recherche sur cette page? [ MVVM | MVP | MVC ]

Voir: Oui, ici c'est… “piano” [ MVVM | MVP | MVC ]

—— C'est la différence la plus importante entre MVVM ET MVP | MVC ———

Présentateur: Merci View,… en attendant, je cherche le terme de recherche sur le Modèle, montrez-lui s'il vous plaît une barre de progression [MVP | MVC]

(Présentateur | Contrôleur appelle le Modèle…) [MVP | MVC]

ViewController: Merci, je rechercherai le terme de recherche sur le Modèle mais je ne vous actualiserai pas directement. Au lieu de cela, je déclencherai des événements à searchResultsListObservable s’il ya un résultat. Donc, vous feriez mieux d'observer à ce sujet. [MVVM]

(Tout en observant n'importe quel déclencheur dans searchResultsListObservable, le View pense qu'il devrait montrer une barre de progression à l'utilisateur, car ViewModel ne lui parlerait pas)

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

ViewModel | Présentateur | Contrôleur: Hé Modèle, Avez-vous trouvé une correspondance pour ce terme de recherche?: “Piano ”[MVVM | MVP | MVC]

Modèle: Hey ViewModel | Présentateur | Contrôleur, laissez-moi vérifier… [MVVM | MVP | MVC]

(Modèle fait une requête dans la base de données de films…) [MVVM | MVP | MVC]

( Après un moment … )

———— C'est le point de divergence entre MVVM, MVP et MVC ————–

Modèle: J'ai trouvé une liste pour vous ViewModel | Présentateur, la voici en JSON “[{“ nom ”:“ Professeur de piano ” , "Année": 2001}, {"nom": "Piano", "année": 1993}] "[MVVM | MVP]

Modèle: Certains résultats sont disponibles, contrôleur. J'ai créé une variable de champ dans mon instance et l'ai renseignée avec le résultat. Son nom est "searchResultsList" [MVC]

(Présentateur | Contrôleur merci Modèle et revient au Affichage) [MVP | MVC]

Présentateur: Merci d'avoir attendu View, j'ai trouvé une liste de résultats correspondants pour vous et les ai classés dans un format pouvant être visualisé: ["Piano Teacher 2001 ″," Piano 1993 "] . Veuillez aussi masquer la barre de progression maintenant [MVP]

Contrôleur: Merci d'avoir attendu View, j'ai demandé à Model de votre requête de recherche. Il dit qu'il a trouvé une liste de résultats correspondants et les a stockés dans une variable nommée "searchResultsList" à l'intérieur de son instance. Vous pouvez l'obtenir à partir de là. Veuillez également masquer la barre de progression maintenant [MVC]

ViewModel: tous les observateurs de searchResultsListObservable soient informés de la présence de cette nouvelle liste au format présentable: ["Piano Teacher 2001", "Piano 1993"]. [MVVM]

Voir: Merci beaucoup Présentateur [MVP]

Voir: Merci “Contrôleur” [MVC] (Maintenant, le View se remet en question : Comment dois-je présenter à l'utilisateur les résultats du Modèle? L'année de production du film doit-elle être la première ou la dernière…?)

View: Oh, il y a un nouveau déclencheur dans searchResultsListObservable…, bien, il y a une liste présentable, il ne me reste plus qu'à la montrer dans une liste. Je devrais également cacher la barre de progression maintenant que j'ai le résultat. [MVVM]

Si vous êtes intéressé, j'ai écrit une série d'articles ici , comparant MVVM, MVP et MVC en mettant en œuvre une application de recherche de film Android.

9
Ali Nem

MVVM ajoute le modèle de vue au mélange. Cela est important, car cela vous permet de tirer parti de l’approche contraignante de WPF, sans mettre toutes les pièces spécifiques de l’interface utilisateur dans votre modèle habituel.

Je me trompe peut-être, mais je ne suis pas sûr que MVVM oblige vraiment le contrôleur à entrer dans le mix. Je trouve le concept plus en phase avec: http://martinfowler.com/eaaDev/PresentationModel.html . Je pense que les gens choisissent de le combiner avec MVC, pas que cela soit intégré au modèle.

9
eglasius

Cela me surprend que ce soit une réponse très votée sans mentionner le Origin de MVVM. MVVM est un terme couramment utilisé dans la communauté Microsoft et il est originated d'après Martin Fowler Modèle de présentation . Donc, pour comprendre le motif du motif et les différences avec d’autres, l’article original sur le motif est la première chose à lire.

9
Cheng

Bien, généralement, MVC est utilisé dans le développement Web et MVVM est le plus populaire dans le développement WPF/Silverlight. Cependant, il arrive que l’architecture Web utilise un mélange de MVC et de MVVM.

Par exemple: vous pouvez utiliser knockout.js et dans ce cas, vous aurez MVVM du côté client. Et le côté serveur de votre MVC peut également changer. Dans les applications complexes, personne n'utilise le modèle pur. Il peut sembler judicieux d’utiliser un ViewModel en tant que "modèle" de MVC et votre modèle réel fera fondamentalement partie de cette machine virtuelle. Cela vous donne une couche d'abstraction supplémentaire.

6
Rinat Galyautdinov

Le contrôleur n'est pas remplacé par un ViewModel dans MVVM, car le ViewModel a une fonctionnalité totalement différente de celle d'un contrôleur. Vous avez toujours besoin d'un contrôleur, car sans contrôleur, votre modèle, ViewModel et View ne feraient pas grand chose ... Dans MVVM, vous avez également un contrôleur, le nom de MVVM est simplement trompeur.

MVVMC est le nom correct à mon humble avis.

Comme vous pouvez le constater, ViewModel n’est qu’un ajout au modèle MVC. Il déplace la logique de conversion (par exemple, convertit un objet en chaîne) du contrôleur vers le ViewModel.

4
Ini

MVVMC, ou peut-être MVC +, semble être une approche viable pour les entreprises ainsi que pour le développement rapide d'applications. Bien qu'il soit agréable de séparer l'interface utilisateur de la logique commerciale et d'interaction, le modèle MVVM "pur" et la plupart des exemples disponibles fonctionnent mieux avec des vues uniques.

Je ne suis pas sûr de vos conceptions, mais la plupart de mes applications contiennent cependant des pages et plusieurs vues (réutilisables). Les modèles de vue doivent donc interagir dans une certaine mesure. L'utilisation de la page en tant que contrôleur irait totalement à l'encontre de l'objectif du MVVM. Par conséquent, le fait de ne pas utiliser l'approche "VM-C" pour la logique sous-jacente peut avoir pour résultat des constructions bien et difficiles à mesure que l'application mûrit. Même dans VB-6, la plupart d'entre nous ont probablement arrêté de coder la logique métier dans l'événement Button et commencé à "relayer" les commandes à un contrôleur, n'est-ce pas? J'ai récemment examiné de nombreux cadres émergents sur ce sujet; mon préféré est clairement l'approche de Magellan (au codeplex). Bon codage!

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

4
der Martin

D'un point de vue pratique, MVC (Model-View-Controller) est un motif. Cependant, MVC, lorsqu'il est utilisé en tant que ASP.net MVC, lorsqu'il est combiné à Entity Framework (EF) et aux "outils puissants" constitue une approche très puissante et partiellement automatisée pour amener des bases de données, des tables et des colonnes sur une page Web. Opérations CRUD ou R (récupération ou lecture) uniquement. Au moins, alors que j'utilisais MVVM, les modèles de vue interagissaient avec des modèles reposant sur des objets métier, eux-mêmes "faits à la main" et après de nombreux efforts, on était chanceux de pouvoir obtenir des modèles aussi bons que ce que EF donne " -de-la-boite ". Du point de vue pratique de la programmation, MVC semble un bon choix car il donne beaucoup d’utilité, mais il existe encore un potentiel d’ajouts inattendus.

2
JosephDoggie

Complémentairement à de nombreuses réponses données, je souhaitais ajouter une perspective supplémentaire à partir du Moderne Web côté client - ou Rich Web Application point de vue.

En effet, de nos jours, les sites Web simples et les grandes applications Web sont généralement construits avec de nombreuses bibliothèques populaires telles que Bootstrap. Construit par Steve Sanderson, Knockout fournit un support pour le modèle MVVM qui imite l’un des comportements les plus importants du modèle: la liaison de données via le modèle de vue. Avec un peu de JavaScript, les données et la logique peuvent être implémentées et peuvent ensuite être ajoutées aux éléments de page avec de simples attributs data-bind HTML, ce qui revient à utiliser de nombreuses fonctionnalités de Bootstrap . Ensemble, ces deux bibliothèques offrent à elles seules un contenu interactif; et lorsqu'elle est combinée avec le routage, cette approche peut donner lieu à une approche simple mais puissante pour la construction de l'application à une seule page .

De même, un cadre client moderne tel que Angular suit le modèle MVC par convention, mais ajoute également un service. Fait intéressant, il est présenté comme modèle-vue-quelle que soit (MVW). (Voir ce message sur Stack Overflow .)

En outre, avec la montée en puissance de Progressive framework Web tels que Angular 2, nous constatons un changement de terminologie et peut-être un nouveau modèle architectural où les composants comprennent une vue ou un modèle et interagir avec un service - qui peuvent tous être contenus dans un module; et une série de modules compose l’application.

2

J'avais l'habitude de penser que MVC et MVVM sont les mêmes. Maintenant, à cause de l'existence de Flux, je peux faire la différence:

Dans MVC, pour chaque vue de votre application, vous avez un modèle et un contrôleur. Je l'appellerais donc view, view model, view controller. Le modèle ne vous dit pas comment une vue peut communiquer avec une autre. Par conséquent, dans différents cadres, il existe différentes implémentations pour cela. Par exemple, il y a des implémentations où les contrôleurs se parlent, alors que dans d'autres implémentations, un autre composant sert d'intermédiaire entre eux. Il existe même des implémentations dans lesquelles les modèles de vue communiquent les uns avec les autres, ce qui constitue une rupture du modèle MVC car le modèle de vue ne doit être accessible que par le contrôleur de vue.

Dans MVVM, vous disposez également d'un modèle de vue pour chaque composant. Le modèle ne spécifie pas comment le point de vue doit influencer le modèle de vue. Par conséquent, la plupart des infrastructures n'incluent que la fonctionnalité du contrôleur dans le modèle de vue. Cependant, MVVM vous indique que les données de votre modèle de vue doivent provenir du modèle, c'est-à-dire de l'intégralité du modèle qui n'est pas conscient ou personnalisé pour une vue spécifique.

Pour démontrer la différence, prenons le modèle de flux. Le modèle de flux indique comment les différentes vues de l'application doivent communiquer. Chaque vue écoute un magasin et déclenche des actions à l'aide du répartiteur. Le répartiteur informe à son tour tous les magasins de l'action qui vient d'être effectuée et les magasins se mettent à jour. Un magasin dans Flux correspond au modèle (général) dans MVVM. ce n'est pas coutume à une vue spécifique. Ainsi, lorsque les utilisateurs utilisent React et Flux, chaque composant React implémente en réalité le modèle MVVM. Lorsqu'une action se produit, le modèle de vue appelle le répartiteur et enfin, il est mis à jour en fonction des modifications apportées au magasin, qui est le modèle. Vous ne pouvez pas dire que chaque composant implémente MVC car dans MVC, seul le contrôleur peut mettre à jour le modèle de vue. Ainsi, MVVM peut travailler avec Flux ensemble (MVVM gère la communication entre la vue et le modèle de vue, et Flux gère la communication entre différentes vues), tandis que MVC ne peut pas fonctionner avec Flux sans enfreindre un principe fondamental.

2
Alon

mvc est côté serveur et mvvm est côté client (navigateur) dans le développement Web.

la plupart du temps, javascript est utilisé pour mvvm dans le navigateur. Il existe de nombreuses technologies côté serveur pour MVC.

1
Maulik Gangani

En bref, dans MVC, Controler connaît la vue (contrôles), tandis que dans MVVM, ViewModel ignore qui l'utilise. ViewModel expose ses propriétés et actions observables à quiconque pourrait être intéressé par son utilisation. Cela facilite les tests car il n'y a aucune référence à l'interface utilisateur dans ViewModel.

1
daneejela

De nos jours, le MVC est mal vu et pas en faveur des développeurs altruistes.

Viper, React, MVVM, c’est bien, MVC est mauvais et merdique…

Vérité ou mythe?

Eh bien, MVC est en effet vieux et la certitude, il a ses défauts, le plus commun de tous, les redoutés "contrôleurs de vue massifs".

Mais bien que les nouvelles architectures susmentionnées apportent des solutions aux problèmes intrinsèques de MVC, elles ont également quelques défauts, ouais "personne n'est parfait".

MVC est génial, les programmeurs sont trop négligents.

1
Helen Wood