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

Essayant de saisir les concepts du MVVM, j’ai déjà lu plusieurs blogs et examiné quelques projets.

D’après ce que j’ai compris, une vue est stupide, elle sait simplement présenter quelque chose qui lui est transmis.

Les modèles ne sont que des données simples et un ViewModel est quelque chose qui agit comme un remplissage entre les deux, qui doit obtenir des informations du modèle et les transmettre à la vue , et la vue doit savoir comment les présenter. Ou inversement, si les informations de la vue changent, elles doivent transmettre la modification au modèle .

Mais je ne sais toujours pas comment appliquer le concept. Quelqu’un peut-il expliquer un scénario très simple pour que je puisse comprendre le concept? J’ai déjà examiné plusieurs projets, mais cela n’a toujours pas de sens, donc si quelqu’un pouvait l’écrire en anglais, ce serait bien.

Merci 🙂

J’aime y penser de cette façon:

Les vues, comme vous dites, sont stupides. Josh Smith, rédacteur de l’ article MSDN fondateur et souvent associé sur MVVM, a déclaré que les vues sont «les vêtements que portent les données». Les vues ne contiennent jamais de données ni ne les manipulent directement, elles sont simplement liées aux propriétés et aux commandes de vos modèles de vues.

Les modèles sont des objects modélisant le domaine de votre application , comme dans les objects métier. Votre application est-elle un magasin de musique? Vos objects modèles seront peut-être des artistes, des albums et des chansons. Votre application est-elle un navigateur org-chart? Vos objects modèles seront peut-être des gestionnaires et des employés. Ces objects de modèle ne sont liés à aucun type de rendu visuel, et ils ne sont même pas directement liés à l’application dans laquelle vous les mettez – vos objects de modèle devraient être parfaitement adaptés à eux-mêmes en tant que famille d’objects représentant de domaine. La couche modèle comprend également des éléments tels que les accesseurs de services.

Cela nous amène à Viewmodels. Que sont-ils? Ce sont des objects qui modélisent une application graphique , ce qui signifie qu’ils fournissent des données et des fonctionnalités à utiliser par les vues. Ils définissent la structure et le comportement de l’application que vous construisez. Pour les objects de modèle, le domaine est quel que soit le domaine que vous choisissez (magasin de musique, navigateur d’organigrammes, 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 objects et des listes en tant que propriétés, ainsi que des éléments comme les commandes. Une commande est simplement un comportement (le plus simple, un appel de méthode) incorporé dans un object qui le transporte – cette idée est importante car les vues sont pilotées par la liaison de données, qui associe des contrôles visuels aux objects. Dans MVVM, vous ne donnez pas à un bouton de méthode Gestionnaire de clic, vous le liez à un object de commande (fourni à partir d’une propriété dans un modèle de vue) contenant la fonctionnalité que vous souhaitez 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 utilisent des 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 à des contrôles ou à d’autres objects qui leur seront associés. Par exemple, avez-vous une vue avec un ListBox? Votre modèle de vue contient certainement une sorte de collection. Votre vue a-t-elle des boutons? Votre vue va certainement avoir des commandes.
  • Il existe quelques types d’objects pouvant être considérés comme des “modèles de vue”. Le type 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 “écran XYZ a une zone de texte, une zone de liste et trois boutons, le modèle a donc besoin d’une chaîne, d’une collection, et trois commandes. ” Un autre type d’object qui s’insère dans la couche viewmodel est une enveloppe autour d’un object de modèle qui lui confère un comportement et le rend plus utilisable par une vue – c’est là que vous entrez dans les concepts de couches “épaisses” et “fines”. Une couche “mince” de vue est un ensemble de modèles de vue qui exposent vos objects de modèle directement aux vues, ce qui signifie que les vues se lient directement aux propriétés des objects du modèle. Cela peut fonctionner pour des choses comme des vues simples en lecture seule, mais que se passe-t-il si vous souhaitez que le comportement soit associé à chaque object? Vous ne voulez pas cela dans le modèle, car le modèle n’est pas lié à l’application, il est uniquement lié à votre domaine. Vous pouvez le placer dans un object qui enveloppe votre object de modèle et offre des données et des comportements plus conviviaux. Cet object wrapper est également considéré comme un viewmodel, et leur obtention d’un calque de vue “plus épais”, où vos vues ne se lient jamais directement à quelque chose d’une classe de modèle. Les collections contiendront des modèles de vue qui encapsulent les modèles au lieu de simplement contenir les modèles eux-mêmes.

Le lapin va plus loin – il y a beaucoup d’idiomes à comprendre comme ValueConverters qui permettent au MVVM de fonctionner, et il y a beaucoup à appliquer lorsque vous commencez à penser à Blendability, aux tests et à la transmission des données dans votre application. chaque modèle de vue a access au comportement dont il a besoin (c’est là que l’dependency injection entre en jeu), mais j’espère que ce qui précède constitue un bon début. La clé est de penser à vos éléments visuels, à votre domaine et à la structure et au comportement de votre application en tant que trois choses différentes.

En utilisant cet article incroyablement utile comme source, voici un résumé pour View , ViewModel et Model .


Vue:

  • 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, leur disposition visuelle et leur style.

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

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

  • La vue définit et gère le comportement visuel de l’interface utilisateur, notamment les animations ou les transitions pouvant ê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 une logique d’interface utilisateur pour implémenter un comportement visuel difficile à exprimer dans XAML ou nécessitant des références directes aux contrôles d’interface utilisateur spécifiques définis dans la vue.

REMARQUE:
Étant donné que le modèle de vue ne doit pas connaître explicitement les éléments visuels spécifiques de la vue, le code permettant de manipuler par programmation des éléments visuels dans 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 requirejse pour prendre en charge un cas d’utilisation ou une tâche 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 les propriétés et les commandes auxquelles la vue peut lier les données. Il notifie la vue de tout changement d’état via les événements de notification de modification via les interfaces INotifyPropertyChanged et INotifyCollectionChanged .

  • Le modèle de vue coordonne l’interaction de la vue avec le modèle. Il peut convertir ou manipuler des données pour qu’elles puissent être facilement utilisées par la vue et 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 les interfaces IDataErrorInfo ou INotifyDataErrorInfo .

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

REMARQUE:
Tout ce qui est important pour le comportement logique de l’application doit entrer dans le modèle de vue. Le code permettant d’extraire ou de manipuler des éléments de données à afficher dans la vue via la 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 métier et la logique métier. Ils sont responsables de la gestion des données de l’application et de leur cohérence et de leur validité en encapsulant les règles métier et la logique de validation des données requirejses.

  • Les classes de modèle ne référencent pas directement la vue ou les classes de modèle de vue et ne dépendent pas de leur implémentation.

  • Les classes de modèle fournissent généralement des événements de notification de modification de propriété et de collection via les interfaces INotifyPropertyChanged et INotifyCollectionChanged . Cela leur permet d’être facilement lié aux données dans la vue. Les classes de modèle qui représentent des collections d’objects dérivent généralement de la classe ObservableCollection .

  • Les classes de modèle fournissent généralement une validation des données et des rapports d’erreurs via les interfaces IDataErrorInfo ou INotifyDataErrorInfo .

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

Je l’ai écrit à peu près comme “un anglais clair” comme je peux le penser dans cette série sur MVVM . En particulier, ce diagramme est probablement l’explication la plus simple et la plus courte.

Cela étant dit, le «modèle» est essentiellement vos données ou vos règles commerciales. Il ne faut vraiment pas savoir comment et où il va être utilisé, et surtout pas quelle technologie va l’utiliser. Le “modèle” est le coeur de l’application – et il ne devrait pas être nécessaire de s’inquiéter de savoir si l’application est WPF, Silverlight, Windows Forms, ASP.NET, etc.

La “vue” est la partie complètement spécifique à la technologie. Dans MVVM, idéalement, la vue devrait être proche de 100% de XAML, car cela apporte des gains considérables en termes de flexibilité.

Cependant, il doit y avoir quelque chose qui traduit les informations du modèle dans une forme utilisable par la technologie disponible – c’est là que le ViewModel entre en jeu. Par exemple, cela “regroupe” souvent les classes de modèle dans un “ViewModel” pour les données spécifiques qui incluent des commandes (pour la logique en cours d’exécution), implémente INotifyPropertyChanged (pour la prise en charge de la liaison de données), etc. Modèle utilisable par la vue.

Une excellente introduction au MVVM peut être trouvée dans la vidéo de Jason Dolinger ici . J’ai gardé la vidéo avec moi pendant un certain temps quand j’ai commencé, c’est très utile.

La création d’un ViewModel présentant une façade cohérente sur le modèle sous-jacent peut être beaucoup plus complexe qu’il n’y paraît. Cet article sur la création d’objects ViewModel montre comment créer un ViewModel et illustre certains problèmes que vous risquez de rencontrer, ainsi que des solutions raisonnables. Quand je l’ai lu, la section traitant des collections manquait, mais il y a encore des points intéressants.