91 votes

Concepts de base de MVVM - que doit faire un ViewModel ?

Pour essayer de saisir les concepts de MVVM, j'ai déjà lu plusieurs blogs et regardé quelques projets.

D'après ce que je comprends, un Voir est stupide, il sait juste comment présenter quelque chose qui lui est passé.

Modèles sont juste les données brutes, et un ViewModel est quelque chose qui agit comme un tampon entre les deux, et qui doit recevoir des informations de la part du Modèle et le transmettre au Voir et le Voir doit savoir comment le présenter. Ou l'inverse, si l'information contenue dans les Voir change, il doit transmettre la modification à l'élément Modèle .

Mais je n'ai toujours aucune idée de la façon d'appliquer ce concept. Quelqu'un peut-il m'expliquer un scénario très simple pour que je puisse saisir le concept ? J'ai déjà examiné plusieurs projets, mais cela n'a toujours pas de sens, alors si quelqu'un pouvait l'écrire en langage clair, ce serait bien.

2 votes

Je ne peux pas être d'accord avec l'affirmation selon laquelle la vue "sait juste comment présenter quelque chose qui lui est transmis". La vue prend des données de VM. Personne ne lui transmet de données. Personne ne connaît la vue. C'est une différence importante avec MVP. Dans MVP (vous pouvez y penser comme à une simple application WPF avec une logique codebehind, c'est un pattern MVP) le codebehind est un présentateur qui passe les données à la vue comme vous l'avez dit.

170voto

nlawalker Points 1874

J'aime y penser de cette façon :

Les opinions, comme vous le dites, sont stupides. Josh Smith, auteur de l'article fondateur et souvent cité en référence. Article de MSDN sur MVVM, a dit que les vues sont "les vêtements que portent les données". Les vues ne contiennent jamais réellement de données ou ne les manipulent pas directement, elles sont juste liées aux propriétés et aux commandes de vos modèles de vues.

Les modèles sont des objets qui modélisent le domaine de votre application comme dans les objets d'entreprise. Votre application est-elle un magasin de musique ? Vos objets modèles seront peut-être des artistes, des albums et des chansons. Votre application est-elle un navigateur d'organigramme ? Vos objets modèles seront peut-être des managers et des employés. Ces objets de modèle ne sont pas liés à un quelconque type de rendu visuel, ni même directement à l'application dans laquelle vous les intégrez. Vos objets de modèle doivent avoir un sens en tant que famille d'objets représentant un domaine quelconque. La couche modèle comprend aussi généralement des éléments tels que des accesseurs de services.

Cela nous amène à Viewmodels. Qu'est-ce que c'est ? Ce sont des objets qui modélisent une application GUI c'est-à-dire qu'ils fournissent des données et des fonctionnalités à utiliser par les vues. Ce sont elles qui définissent la structure et le comportement de l'application réelle que vous construisez. Pour les objets du modèle, le domaine est celui que vous choisissez (magasin de musique, navigateur de cartes d'orgue, etc.), mais pour le modèle de vue, le domaine est une application graphique. Vos modèles de vue vont encapsuler le comportement et les données de tout ce que fait votre application. Ils vont exposer des objets et des listes en tant que propriétés, ainsi que des choses comme des commandes. Une commande est simplement un comportement (au plus simple, un appel de méthode) enveloppé dans un objet qui le transporte - cette idée est importante car les vues sont pilotées par le databinding, qui attache des contrôles visuels aux objets. Dans MVVM, vous ne donnez pas à un bouton une méthode de traitement du clic, vous le liez à un objet de commande (servi par une propriété d'un modèle de vue) qui contient la fonctionnalité que vous voulez exécuter lorsque vous cliquez dessus.

Pour moi, les éléments les plus déroutants étaient les suivants :

  • Même si les modèles de vue sont des modèles d'une application graphique, ils ne font pas directement référence ou n'utilisent pas de concepts visuels. Par exemple, vous ne voulez pas de références aux contrôles Windows dans vos ViewModels - ces choses vont dans la vue. Les ViewModels exposent simplement les données et les comportements aux contrôles ou aux autres objets qui s'y lient. Par exemple, avez-vous une vue avec une ListBox ? Il est presque certain que votre modèle de vue contiendra une sorte de collection. Votre vue comporte-t-elle des boutons ? Il est presque certain que votre modèle de vue contiendra des commandes.
  • Il existe plusieurs types d'objets qui peuvent être considérés comme des "modèles de vue". Le type de modèle de vue le plus simple à comprendre est celui qui représente directement un contrôle ou un écran dans une relation 1:1, comme dans "l'écran XYZ a une zone de texte, une zone de liste et trois boutons, donc le modèle de vue a besoin d'une chaîne, d'une collection et de trois commandes". Un autre type d'objet qui s'inscrit dans la couche viewmodel est une enveloppe autour d'un objet de modèle qui lui donne un comportement et le rend plus utilisable par une vue - c'est là que vous entrez dans les concepts de couches viewmodel "épaisses" et "fines". Une couche de modèle de vue "mince" est un ensemble de modèles de vue qui expose vos objets de modèle directement aux vues, ce qui signifie que les vues se lient directement aux propriétés des objets de modèle. Cela peut fonctionner pour des choses comme des vues simples, en lecture seule, mais que faire si vous voulez avoir un comportement associé à chaque objet ? Vous ne voulez pas que cela soit dans le modèle, parce que le modèle n'est pas lié à l'application, il est seulement lié à votre domaine. Vous pouvez le mettre dans un objet qui enveloppe votre objet modèle et offre des données et des comportements plus faciles à lier. Cet objet d'enveloppement est également considéré comme un modèle de vue, et le fait de les avoir permet d'obtenir une couche de modèle de vue "plus épaisse", dans laquelle vos vues ne se lient jamais directement à quoi que ce soit dans une classe de modèle. Les collections contiennent des viewmodels qui enveloppent les modèles au lieu de contenir les modèles eux-mêmes.

Le terrier du lapin va plus loin - il y a beaucoup d'idiomes à comprendre comme les ValueConverters qui permettent à MVVM de fonctionner, et il y a beaucoup de choses à appliquer quand vous commencez à penser à des choses comme la compatibilité, les tests, et comment faire passer les données dans votre application et s'assurer que chaque viewmodel a accès au comportement dont il a besoin (c'est là que l'injection de dépendance entre en jeu), mais nous espérons que ce qui précède est un bon début. La clé est de penser à vos visuels, votre domaine, et la structure et le comportement de votre application réelle comme trois choses différentes.

3 votes

+1 - J'ai atterri ici parce que j'étais confus par un ViewModel "wrapper" rencontré dans certains exemples de code. Merci de m'avoir éclairé sur ce point :-)

1 votes

Excellente réponse. J'aimerais pouvoir ajouter 10.

1 votes

Beaucoup d'articles et de blogs ne parlent que des "fonctionnalités clés" de MVVM, mais quand on essaie de s'y mettre, les choses commencent à être très compliquées, comme "Comment naviguer dans ces vues ? "Quelle est la granularité appropriée lorsque nous concevons des ViewModels ?" "Une vue doit-elle avoir un ViewModel correspondant ou un ViewModel peut-il être réutilisé dans différentes vues ? "Votre clarification sur le ViewModel composé avec le "Slim VM" et "Thick VM" a vraiment du sens!Je l'essaie, il fonctionne bien jusqu'à présent! :)

26voto

Dom Points 7921

Utilisation de cet article incroyablement utile comme source, voici un résumé pour Voir , ViewModel y Modèle .


Voir :

  • La vue est un élément visuel, tel qu'une fenêtre, une page, un contrôle utilisateur ou un modèle de données. La vue définit les contrôles contenus dans la vue ainsi que leur disposition visuelle et leur style.

  • La vue fait référence au modèle de vue par le biais de son DataContext propriété. Les contrôles de la vue sont liés par des données aux propriétés et aux commandes exposées par le modèle de vue.

  • La vue peut personnaliser le comportement de liaison de données entre la vue et le modèle de vue. Par exemple, la vue peut utiliser des convertisseurs de valeurs pour formater les données à afficher dans l'interface utilisateur, ou utiliser des règles de validation pour fournir à l'utilisateur une validation supplémentaire des données d'entrée.

  • La vue définit et gère le comportement visuel de l'interface utilisateur, comme les animations ou les transitions qui peuvent être déclenchées par un changement d'état dans le modèle de vue ou par l'interaction de l'utilisateur avec l'interface utilisateur.

  • Le code-behind de la vue peut définir la logique de l'interface utilisateur pour mettre en œuvre un comportement visuel difficile à exprimer en XAML ou qui nécessite des références directes aux contrôles spécifiques de l'interface utilisateur définis dans la vue.

NOTE :
Étant donné que le modèle de vue ne doit pas avoir de connaissance explicite des éléments visuels spécifiques de la vue, le code permettant de manipuler par programme les éléments visuels de la vue doit résider dans le code-behind de la vue ou être encapsulé dans un comportement.


Voir le modèle :

  • Le modèle de vue est une classe non visuelle et ne dérive d'aucune classe de base WPF ou Silverlight. Il encapsule la logique de présentation requise pour prendre en charge un cas d'utilisation ou une tâche de l'utilisateur dans l'application. Le modèle de vue est testable indépendamment de la vue et du modèle.

  • Le modèle de vue ne fait généralement pas directement référence à la vue. Il implémente des propriétés et des commandes auxquelles la vue peut se lier par des données. Il notifie la vue de tout changement d'état par le biais d'événements de notification de changement via la fonction INotifyPropertyChanged y INotifyCollectionChanged interfaces.

  • Le modèle de vue coordonne l'interaction de la vue avec le modèle. Il peut convertir ou manipuler les données afin qu'elles puissent être facilement consommées par la vue et peut implémenter des propriétés supplémentaires qui peuvent ne pas être présentes sur le modèle. Il peut également implémenter la validation des données via la fonction IDataErrorInfo o INotifyDataErrorInfo interfaces.

  • Le modèle de vue peut définir des états logiques que la vue peut représenter visuellement pour l'utilisateur.

NOTE :
Tout ce qui est important pour le comportement logique de l'application doit aller dans le modèle de vue. Le code permettant de récupérer ou de manipuler les éléments de données qui doivent être affichés dans la vue par liaison de données doit résider dans le modèle de vue.


Modèle :

  • Les classes de modèle sont des classes non visuelles qui encapsulent les données et la logique métier de l'application. Elles sont chargées de gérer les données de l'application et de garantir leur cohérence et leur validité en encapsulant les règles de gestion et la logique de validation des données requises.

  • Les classes de modèle ne font pas directement référence aux classes de vue ou de modèle de vue et ne dépendent pas de la manière dont elles sont mises en œuvre.

  • Les classes de modèle fournissent généralement des événements de notification de changement de propriété et de collection par le biais de la fonction INotifyPropertyChanged y INotifyCollectionChanged interfaces. Cela leur permet d'être facilement liés aux données dans la vue. Les classes de modèle qui représentent des collections d'objets dérivent généralement de l'interface ObservableCollection<T> classe.

  • Les classes de modèle fournissent généralement une validation des données et un rapport d'erreur par le biais de l'un ou l'autre des éléments suivants IDataErrorInfo o INotifyDataErrorInfo interfaces.

  • Les classes de modèle sont généralement utilisées en conjonction avec un service ou un référentiel qui encapsule l'accès aux données et la mise en cache.

19voto

Reed Copsey Points 315315

J'ai écrit tout ça dans un langage aussi simple que possible dans cette série sur MVVM . En particulier, ce schéma est probablement l'explication la plus simple et la plus courte.

Cela étant dit, le "modèle" est essentiellement constitué de vos données ou de vos règles de gestion. Il ne devrait pas vraiment savoir comment ou où il va être utilisé, et surtout pas quelle technologie va l'utiliser. Le "modèle" est le noyau de l'application - et il ne devrait pas avoir à s'inquiéter de savoir si l'application est WPF, Silverlight, Windows Forms, ASP.NET, etc - c'est juste "lui-même" dans une forme pure.

La "vue" est la partie qui est complètement spécifique à la technologie. Dans MVVM, l'idéal est que la vue soit presque entièrement en XAML, car cela permet de gagner énormément en flexibilité.

Cependant, il faut que quelque chose traduise les informations du modèle sous une forme utilisable par la technologie en question - c'est là que le ViewModel entre en jeu. Par exemple, les classes du modèle sont souvent "enveloppées" dans un "ViewModel" pour ces données spécifiques, qui comprend des commandes (pour l'exécution de la logique), met en œuvre les éléments suivants INotifyPropertyChanged (pour la prise en charge des liaisons de données), etc. C'est tout - c'est le pont qui rend le modèle utilisable par la vue.

0 votes

Ok, merci. Je pensais que le modèle était un objet et que le ViewModel était une méthode de manipulation des objets, de sorte qu'une vue puisse comprendre les "objets" du modèle. Mais on m'a dit que c'était faux, que le ViewModel lui-même était aussi un objet. Je pense que c'est ce qui me perturbe vraiment.

0 votes

@Rosie : Je vous recommande de lire (ou au moins de survoler) la série que j'ai citée. Je l'ai écrite spécifiquement parce qu'il y a peu (presque aucun) article sur MVVM qui ne suppose pas que vous comprenez déjà MVC ou MVP, etc. C'est vraiment une transition " pas à pas " ;)

0 votes

En réalisant que c'est le zombie-threading d'une petit ... Votre diagramme indique que la VM contient "Application-Specific State". et Logique " (c'est moi qui souligne). Cela signifie-t-il que vous pensez que la VM pourrait/devrait contenir une logique d'assurance qualité des données ? Le fichier RssWpfMVVM.csproj correspondant ne semble pas comporter d'AQ évidente dans ses deux modèles de vue.

1voto

Filipe Miguel Points 337

Une excellente introduction à MVVM se trouve dans la vidéo de Jason Dolinger. aquí . J'ai gardé la vidéo avec moi pendant un certain temps lorsque j'ai commencé, elle est vraiment utile.

1 votes

Le lien est mort

1 votes

@ibrahimmahrir ~ J'ai mis à jour le lien vers une URL fonctionnelle. Je suis en train de télécharger la vidéo.

0voto

Sprotty Points 415

Construire un ViewModel qui présente une façade cohérente sur le modèle sous-jacent peut être beaucoup plus complexe qu'il n'y paraît. Ce site article sur la construction d'objets ViewModel montre comment construire un ViewModel, et illustre certains des problèmes que vous êtes susceptibles de rencontrer - avec ce qui semble être des solutions raisonnables. Quand je l'ai lu, il manquait la section sur la gestion des collections, mais il y a quand même des points intéressants.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X