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.
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.