Clarification MVVM


15

Nous sommes sur le point d'écrire notre première application WPF et nous nous familiarisons avec le modèle MVVM. Nous avons construit de nombreuses applications Winform et avons une architecture qui a été très réussie pour nous. Nous avons un peu de mal à traduire cette architecture ou à déterminer où certaines parties de notre architecture s'intègrent dans le modèle MVVM.

Historiquement, nous avons un Gui (l'exe principal) qui communique ensuite avec une DLL BusinessLogic. BusinessLogic communique avec une DLL DAL via un service Web et le DAL interagit avec la base de données. Les DAL, BusinessLogic et GUI font tous référence à la même DLL BusinessObjects.

Architecture AsIs

Une partie de la transition vers MVVM est assez simple. Notre Gui contiendra toujours les vues, nos BusinessOjbects contiendront toujours le modèle et notre DAL interagira toujours avec la base de données (bien que la technologie pour les implémenter puisse changer).

Ce dont nous ne sommes pas sûrs, c'est de notre composant BusinessLogic. Historiquement, cela fournirait des fonctions à l'interface graphique pour appeler puis remplir les contrôles dans les vues (c'est-à-dire GetCustomerList qui retournerait une liste d'objets Customer ou les fonctions CRUD typiques).

Le principal problème que nous avons est de savoir si le modèle MVVM nécessiterait un composant supplémentaire pour héberger les ViewModels ou si nous modifions simplement notre façon de penser et migrons ce que nous avons utilisé comme composant BusinessLogic vers les ViewModels?

Notre composant BusinessLogic représente-t-il les ViewModels?


Cela ressemble un peu à une solution à la recherche d'un problème. Y a-t-il une raison impérieuse pour laquelle vous passez à MVVM? Je suis fan du modèle mais votre solution précédente ne fonctionnait-elle pas? Le modèle de vue est comme un présentateur superviseur. Il contient la logique de présentation et les données de surface via la liaison de données. Il devrait connaître votre logique métier et être en mesure d'atteindre ce niveau, mais je ne ferais pas fondre la logique métier dans le modèle de vue lui-même.
Jeremy Likness

Réponses:


19

En général, je ne placerais pas la logique métier dans la couche du modèle de vue. Mais le terme "Business Logic" est trompeur.

Eric Evans utilise un modèle où la logique métier est divisée en deux catégories

  • Logique de domaine - Logique liée au domaine de problème réel que vous résolvez
  • Logique d'application - Logique liée au fait que vous construisez une application

Il cite l'exemple d'une application comptable. Les règles concernant les comptes, les publications, les comptes de taxes, etc. sont des règles de domaine, des règles relatives au domaine de la comptabilité. La logique de l'import / export CSV n'a rien à voir avec le domaine de la comptabilité. Ces règles existent uniquement parce que nous construisons une application logicielle. Ce sont des exemples de logique d'application.

Les règles de domaine ne doivent JAMAIS entrer dans la couche du modèle de vue. Si vous suivez le modèle MVVM, les règles de domaine vont, sans aucun doute, dans la couche modèle.

Les règles d'application, comme l'importation / exportation CSV, peuvent aller dans la couche du modèle de vue. Mais personnellement, je préférerais séparer cela en une couche logique d'application distincte.

Le modèle d'affichage doit être très simple. Recherche des données nécessaires à la vue dans le modèle correspondant, mise à jour du modèle lorsque la vue change, écoute des événements dans le modèle et propagation de ces événements à la vue, permettant à la vue d'être mise à jour lorsque le modèle est mis à jour en arrière-plan (le cas échéant).

Personnellement, je m'assurerais que la couche du modèle de vue ne contient qu'un seul type de logique, la logique de présentation.


1
Excellente réponse. J'aime le fait de m'assurer que le ViewModel ne contient que la logique de présentation. Pouvez-vous ajouter un lien lié à votre point Eric Evans?
user7676

Je doute que je puisse trouver un lien, car je pense que je l'ai obtenu de son livre, Domain-Driven Design. Quoi qu'il en soit, je pense que c'est un excellent exemple de la différence entre le domaine et la logique d'application. Plus d'informations sur le livre ici books.google.dk/books/about/…
Pete

5

Oui.

La couche logique métier est représentée par la couche VM. Il vous suffit donc de migrer votre modèle mental.

Pour vous aider dans la migration de votre modèle mental, une légère nuance est que les objets GUI (View) doivent être liés aux objets de la couche VM. Cette liaison se traduit par | implique que la vue n'est plus la couche qui "fait l'appel" afin de récupérer autre chose. L'appel pour la récupération des données proviendra de la machine virtuelle à la place.

Pour mieux expliquer: Oui, un objet dans la vue devra changer afin de déclencher la séquence des choses qui feront l'appel. Mais la vue n'appelle pas elle-même. Et dans ce cas, je considère qu'un clic sur un bouton équivaut à quelque chose dans la vue qui change, mais qui ne fait toujours pas l'appel.

Dans le premier cas, cet objet View sera lié à un objet VM. La machine virtuelle doit écouter un événement de modification de propriété sur l'objet lié. L'événement de changement d'objet peut ensuite être câblé à une fonction VM pour effectuer l'appel de modèle.

Dans le deuxième cas (événement de clic de bouton), l'événement de changement (clic) peut être câblé à un appel de fonction exposé par la machine virtuelle.

Quoi qu'il en soit, c'est toujours un événement qui se séquence dans la machine virtuelle qui appelle ensuite le modèle qui à son tour appelle le DAL / DB.

J'en parle parce que du code WinForm est utilisé pour passer un appel à la couche DB directement à partir du code-behind de l'interface graphique WinForm. Cette approche rompt la séparation qu'offre MVVM.


Merçi pour la confirmation. Nous comprenons la nuance de la façon dont la vue interagit avec le ViewModel et nous nous en tiendrons au modèle de liaison et abandonnerons "l'appel".
user7676

J'ai remarqué que cette réponse a perdu un vote positif. Je serais curieux de savoir si le downvoter commenterait pourquoi? Ou peut-être ajoutez leur propre réponse s'ils ne partagent pas ce point de vue.
user7676

1
Je conviens que la couche logique métier est représentée par la couche VM, mais je pense que certaines parties de votre réponse peuvent prêter à confusion. La Viewcouche est censée être une représentation visuelle du ViewModel ou du modèle, donc plutôt que de dire que l'événement click est câblé à un appel de fonction sur la machine virtuelle, une meilleure définition serait de dire que la commande dans la machine virtuelle est rendue sous la forme d'un bouton dans la couche View. Aussi, je ne généralement pas comme ma couche modèle pouvoir accéder au DAL directement, donc mon flux d'application serait généralement aller VM -> DAL -> DB, où les VMet les DALdeux utilisent les simples Modelobjets de données.
Rachel

4
Je ne suis pas d'accord avec cette réponse. ViewModel est un modèle de la vue, il contient une logique de vue et non une logique métier. ViewModels font partie de la couche de présentation
simoraman

1
@simoraman - Le modèle MVPVM est conforme à ce que vous proposez. Je pense que MVPVM est un bon modèle, mais un peu lourd pour les petites applications. Je vous encourage vraiment à mettre vos réflexions dans une réponse et à contribuer à cette question.

5

Vous avez raison de penser que vous remplaceriez essentiellement votre DLL BusinessLogic par votre couche ViewModel, mais je pense que la plus grande différence à laquelle vous serez confronté est de savoir comment la couche View / UI interagit avec votre couche ViewModel / BusinessLogic.

Dans WinForms, l'interface graphique est votre application et est responsable du flux d'application. Dans WPF / MVVM, vos ViewModels sont votre application et l'interface graphique devient juste une interface conviviale pour interagir avec les ViewModels.

Par exemple, avec WinForms, vous pouvez avoir un DataGrid et un Button, et lorsque vous cliquez sur ce Button, vous appelez BusinessLogicLayer.GetProducts()et chargez les objets Product résultants dans le DataGrid.

Avec WPF, vous auriez un ViewModel qui contient un ObservableCollection<Products>et un ICommand GetProducts, et l'exécution de la commande appelle le DAL et charge la collection de produits. Mais pour fournir une interface conviviale pour cela, vous devez créer une vue qui rend votre ViewModel à l'aide d'un DataGrid pour la collection Products et d'un bouton pour la commande GetProducts.

J'ai en fait écrit un article assez récent pour mon blog sur le changement de mentalité lors du passage de Winforms à WPF sur mon blog , et je pense que la meilleure façon de résumer la différence est avec ces images:


1
Je suis d'accord avec GlenH7, c'est une bonne réponse pour quelqu'un qui démarre avec WPF. Nous obtenons le changement de paradigme de l'interaction entre le View et le ViewModel, donc ce n'était pas vraiment le sujet de la question que j'ai posée.
user7676
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.