Je suis en train de parcourir quelques articles sur le MVVM, principalement celui-ci et celui-ci.
Ma question spécifique est : Comment communiquer les changements du modèle du Model au ViewModel?
Dans l'article de Josh, je ne vois pas qu'il fasse cela. Le ViewModel demande toujours les propriétés du modèle. Dans l'exemple de Rachel, elle demande que le modèle implémente INotifyPropertyChanged
, et déclenche des événements du modèle, mais ceux-ci sont destinés à être consommés par la vue elle-même (voir son article/code pour plus de détails sur pourquoi elle fait cela).
Nulle part je ne vois d'exemples où le modèle alerte le ViewModel des changements aux propriétés du modèle. Cela me préoccupe peut-être que ce ne soit pas fait pour une raison. Existe-t-il une norme pour informer le ViewModel des changements dans le modèle? Il semblerait que cela soit nécessaire car (1) il pourrait y avoir plus d'un ViewModel pour chaque modèle, et (2) même s'il n'y a qu'un seul ViewModel, une action sur le modèle pourrait entraîner d'autres changements de propriétés.
Je soupçonne qu'il pourrait y avoir des réponses/commentaires du type "Pourquoi voudriez-vous faire cela?" donc voici une description de mon programme. Je suis nouveau dans le MVVM donc peut-être que tout mon design est défectueux. Je vais le décrire brièvement.
Je programme quelque chose de plus intéressant (du moins, pour moi!) que les classes "Client" ou "Produit". Je programme le Blackjack.
J'ai une vue qui n'a pas de code derrière et qui se contente de lier des propriétés et des commandes dans le ViewModel (voir l'article de Josh Smith).
Que cela plaise ou non, j'ai eu l'attitude que le modèle devrait contenir non seulement des classes telles que CarteJouée
, Tas
, mais aussi la classe JeuBlackJack
qui garde l'état de l'ensemble du jeu, et sait quand le joueur a dépassé, que le croupier doit piocher des cartes, et quel est le score actuel du joueur et du croupier (moins de 21, 21, dépassé, etc.).
Depuis JeuBlackJack
j'expose des méthodes comme "TirerCarte" et il m'est venu à l'esprit que lorsque une carte est tirée, des propriétés comme ScoreCarte
, et EstPété
devraient être mises à jour et ces nouvelles valeurs communiquées au ViewModel. Peut-être que c'est une pensée fautive?
On pourrait adopter l'attitude que le ViewModel a appelé la méthode TirerCarte()
donc il devrait savoir demander un score actualisé et savoir s'il a dépassé ou non. Des opinions?
Dans mon ViewModel, j'ai la logique pour obtenir une image réelle d'une carte de jeu (basée sur la couleur, le rang) et la rendre disponible pour la vue. Le modèle ne devrait pas se soucier de cela (peut-être qu'un autre ViewModel utiliserait simplement des nombres au lieu d'images de cartes de jeu). Bien sûr, certains me diront peut-être que le modèle ne devrait même pas avoir le concept d'un jeu de Blackjack et que cela devrait être géré dans le ViewModel?
3 votes
L'interaction que vous décrivez semble nécessiter uniquement un mécanisme d'événement standard. Le modèle peut exposer un événement appelé
OnBust
, et le MV peut s'y abonner. Je suppose que vous pourriez également utiliser une approche IEA.0 votes
Je vais être honnête, si je devais créer une véritable « application » de blackjack, mes données seraient cachées derrière quelques couches de services/proxies et un niveau pédant de tests unitaires semblables à A+B = C. Ce serait le proxy/service qui informerait des changements.
1 votes
Merci à tous! Malheureusement, je ne peux choisir qu'une seule réponse. Je choisis celle de Rachel en raison des conseils supplémentaires en architecture et du nettoyage de la question d'origine. Mais il y avait beaucoup de bonnes réponses et je les apprécie. -Dave
0 votes
Voir aussi la réponse de Josh G avec un lien vers Design Patterns - Problèmes et solutions avec Model-View-ViewModel de Robert McCarter
3 votes
FWIW: Après avoir lutté pendant plusieurs années avec les complexités de maintenir à la fois le concept de VM et M par domaine, je crois désormais que les deux fails DRY ; la séparation nécessaire des préoccupations peut être plus facilement réalisée en ayant deux INTERFACES sur un seul objet - une "Interface de Domaine" et une "Interface de ViewModel". Cet objet peut être passé à la fois à la logique métier et à la logique de vue, sans confusion ni manque de synchronisation. Cet objet est un "objet d'identité" - il représente de manière unique l'entité. Maintenir la séparation du code de domaine par rapport au code de vue nécessite alors de meilleurs outils pour le faire à l'intérieur d'une classe.