MVVM est-il inutile?

L’implémentation orthodoxe de MVVM est-elle inutile? Je crée une nouvelle application et j’ai considéré Windows Forms et WPF. J’ai choisi WPF car il est évolutif et offre beaucoup de flexibilité. Il y a moins de code et plus facile d’apporter des modifications significatives à votre interface utilisateur à l’aide de XAML.

Étant donné que le choix de WPF est évident, je me suis dit que je pourrais tout aussi bien utiliser MVVM comme architecture d’application, car elle offre des possibilités de fusion, de séparation et de testabilité. Théoriquement, il semble beau comme le Saint-Graal de la programmation de l’interface utilisateur. Cette brève aventure; cependant, s’est transformé en un véritable casse-tête. Comme prévu dans la pratique, je constate que j’ai échangé un problème pour un autre. J’ai tendance à être un programmeur obsessionnel en ce sens que je veux faire les choses correctement pour obtenir les bons résultats et éventuellement devenir un meilleur programmeur. Le pattern MVVM vient de passer à côté de mon test de productivité et vient de devenir un gros bidouillage!

Le cas clair est l’ajout d’une prise en charge pour une boîte de dialog Modal. La manière correcte consiste à mettre en place une boîte de dialog et à la lier à un modèle de vue. Faire fonctionner ceci est difficile. Afin de bénéficier du modèle MVVM, vous devez dissortingbuer du code à plusieurs endroits dans les couches de votre application. Vous devez également utiliser des constructions de programmation ésotériques comme des modèles et des expressions lamba. Des choses qui vous font regarder l’écran en vous grattant la tête. Cela rend la maintenance et le débogage cauchemardesques, comme je l’ai récemment découvert. J’avais une boîte à outils fonctionnant correctement jusqu’à ce que je reçoive une exception la deuxième fois que je l’invoquais, en disant qu’elle ne pouvait plus afficher la boîte de dialog une fois fermée. J’ai dû append un gestionnaire d’événement pour la fonctionnalité de fermeture à la fenêtre de dialog, un autre dans l’implémentation IDialogView et enfin un autre dans IDialogViewModel. Je pensais que le MVVM nous sauverait d’une telle piraterie extravagante!

Plusieurs personnes ont des solutions concurrentes à ce problème et elles sont toutes des hacks et ne fournissent pas une solution propre, facilement réutilisable et élégante. La plupart des kits d’outils MVVM couvrent les boîtes de dialog et, lorsqu’ils y répondent, ils ne sont que des zones d’alerte ne nécessitant pas d’interfaces personnalisées ou de modèles de vue.

Je prévois d’abandonner le schéma d’affichage MVVM, du moins son implémentation orthodoxe. Qu’est-ce que tu penses? Cela vous a-t-il valu la peine si vous en aviez? Est-ce que je ne suis qu’un programmeur incompétent ou est-ce que MVVM n’est pas ce qu’il est censé être?

Désolé si ma réponse est devenue un peu longue, mais ne m’en voulez pas! Votre question est longue aussi.

En résumé, MVVM n’est pas inutile.

Le cas clair est l’ajout d’une prise en charge pour une boîte de dialog Modal. La manière correcte consiste à mettre en place une boîte de dialog et à la lier à un modèle de vue. Faire fonctionner ceci est difficile.

Oui, c’est vraiment
Cependant, MVVM vous permet de séparer l’apparence de l’interface utilisateur de ses logiques. Personne ne vous oblige à l’utiliser partout, et personne ne tient un pistolet contre votre front pour vous faire créer un ViewModel distinct pour tout.

Voici ma solution pour cet exemple particulier:
La façon dont l’interface utilisateur gère une certaine entrée n’est pas l’affaire de ViewModel. J’appendais du code au fichier .xaml.cs de View, qui instancie la boîte de dialog et définit la même instance de ViewModel (ou autre chose, si nécessaire) comme DataContext.

Afin de bénéficier du modèle MVVM, vous devez dissortingbuer du code à plusieurs endroits dans les couches de votre application. Vous devez également utiliser des constructions de programmation ésotériques comme des modèles et des expressions lamba.

Eh bien, vous n’avez pas besoin de l’utiliser à plusieurs endroits. Voici comment je le résoudrais:

  • Ajoutez le XAML à la vue et rien dans le fichier .xaml.cs
  • Écrivez chaque logique d’application (à l’exception des éléments qui fonctionneraient directement avec les éléments d’interface utilisateur) dans un ViewModel
  • Tout le code qui devrait être fait par l’interface utilisateur mais qui n’a rien à voir avec la logique métier va dans les fichiers .xaml.cs

Je pense que le but de MVVM est avant tout de séparer la logique de l’application et de l’interface utilisateur concrète, permettant ainsi des modifications faciles (ou un remplacement complet) de l’interface utilisateur.
J’utilise le principe suivant: la vue peut savoir et assumer tout ce qu’elle veut du ViewModel, mais le ViewModel ne peut rien savoir sur la vue.
WPF fournit un bon modèle de liaison que vous pouvez utiliser pour atteindre exactement cela.

(BTW, les modèles et les expressions lambda ne sont pas ésotériques s’ils sont utilisés correctement. Mais si vous ne le souhaitez pas, ne les utilisez pas.)

Des choses qui vous font regarder l’écran en vous grattant la tête.

Oui, je connais le sentiment. Exactement ce que je ressentais quand j’ai vu le MVVM pour la première fois. Mais une fois que vous aurez compris, cela ne sera plus mauvais.

J’avais une boîte qui fonctionnait bien …

Pourquoi voudriez-vous placer un ViewModel derrière une boîte de dialog? Aucun point dans cela.

La plupart des kits d’outils MVVM couvrent les boîtes de dialog et, lorsqu’ils y répondent, ils ne sont que des zones d’alerte ne nécessitant pas d’interfaces personnalisées ou de modèles de vue.

Oui, car le simple fait qu’un élément d’interface utilisateur soit dans la même fenêtre, ou dans une autre fenêtre, ou qu’il tourne autour de Mars pour le moment, ne concerne pas les ViewModels.
Séparation des préoccupations

MODIFIER:

Voici une très belle vidéo dont le titre est Build your own MVVM framework . Cela vaut la peine de regarder.

Faire fonctionner ceci est difficile. Afin de bénéficier du modèle MVVM, vous devez dissortingbuer du code à plusieurs endroits dans les couches de votre application. Vous devez également utiliser des constructions de programmation ésotériques comme des modèles et des expressions lamba.

Pour une boîte de dialog modale courante? Vous faites certainement quelque chose de mal ici – l’implémentation de MVVM ne doit pas nécessairement être aussi complexe.

Étant donné que vous êtes nouveau sur MVVM et WPF, il est probable que vous utilisiez des solutions sous-optimales partout et que cela complique inutilement les choses – du moins, je l’ai fait lorsque j’ai commencé à utiliser WPF. Assurez-vous que le problème est vraiment MVVM et pas votre implémentation avant d’abandonner.

MVVM, MVC, Document-View, etc. est une ancienne famille de modèles. Il existe des inconvénients, mais pas de failles fatales du type que vous décrivez.

Je traite le problème des dialogs en sortingchant. My MainWindow implémente une interface IWindowServices qui expose toutes les boîtes de dialog spécifiques à l’application. Mes autres ViewModels peuvent ensuite importer l’interface de services (j’utilise MEF, mais vous pouvez facilement passer l’interface via des constructeurs manuellement) et l’utiliser pour accomplir ce qui est nécessaire. Par exemple, voici à quoi ressemble l’interface pour une petite application utilitaire:

//Wrapper interface for dialog functionality to allow for mocking during tests public interface IWindowServices { bool ExecuteNewProject(NewProjectViewModel model); bool ExecuteImportSymbols(ImportSymbolsViewModel model); bool ExecuteOpenDialog(OpenFileDialog dialog); bool ExecuteSaveDialog(SaveFileDialog dialog); bool ExecuteWarningConfirmation(ssortingng text, ssortingng caption); void ExitApplication(); } 

Cela met toutes les exécutions Dialog en un seul endroit et peut être facilement éliminé pour les tests unitaires. Je suis le modèle que le client de la boîte de dialog doit créer le ViewModel approprié, qu’ils peuvent ensuite configurer selon les besoins. Les blocs d’appel Execute et ensuite le client peuvent consulter le contenu du ViewModel pour voir les résultats du dialog.

Une conception MVVM plus «pure» peut être importante pour une grande application, où vous avez besoin d’une isolation plus propre et d’une composition plus complexe, mais pour les petites et moyennes applications, une approche pratique, avec des services appropriés pour exposer les crochets .

Les modèles de conception sont là pour vous aider, pas pour vous empêcher. Être un bon développeur consiste en partie à savoir quand “casser les règles”. Si MVVM est lourd pour une tâche et que vous avez déterminé que la valeur future ne vaut pas la peine, n’utilisez pas le modèle. Par exemple, comme d’autres affiches l’ont dit, pourquoi passer par toutes les règles pour mettre en place une boîte simple?

Les modèles de conception ne devaient jamais être suivis dogmatiquement.

Je suis au milieu d’un développement MVVM assez complexe utilisant PRISM, j’ai donc dû faire face à ce genre de problèmes.

Mes conclusions personnelles:

MVVM vs MVC / PopUps & co

  • MVVM est vraiment un modèle génial et dans la plupart des cas, il remplace complètement MVC grâce à la puissante liaison de données dans WPF
  • Appeler votre couche de services directement à partir du présentateur est une implémentation légitime dans la plupart des cas.
  • Même les scénarios List / Detail assez complexes peuvent être implémentés par MVVM pur grâce à la syntaxe {Binding Path = /}
  • Néanmoins, lorsque la coordination complexe entre plusieurs vues doit être mise en œuvre, un contrôleur obligatoire
  • Les événements peuvent être utilisés; l’ancien modèle qui implique le stockage des instances IView (ou AbstractObserver) dans le contrôleur est obsolète
  • Le contrôleur peut être injecté dans chaque présentateur par conteneur IOC
  • Le service IEventAggregator de Prism est une autre solution possible si la seule utilisation du contrôleur est la répartition des événements (dans ce cas, il peut remplacer complètement le contrôleur)
  • Si des vues doivent être créées dynamicment, ceci est un travail très approprié pour le contrôleur (dans le prisme, le contrôleur recevra un gestionnaire IRegion (IOC))
  • Les boîtes de dialog modales sont pour la plupart obsolètes dans les applications composites modernes, sauf pour les opérations réellement bloquantes telles que les confirmations obligatoires; dans ces cas, l’activation modale peut être extraite en tant que service appelé à l’intérieur du contrôleur et implémentée par une classe spécialisée, ce qui permet également d’effectuer des tests unitaires avancés au niveau de la présentation. Par exemple, le contrôleur appellera IConfirmationService.RequestConfirmation («êtes-vous sûr»), ce qui déclenchera l’affichage d’une boîte de dialog modale à l’exécution et pourra être facilement simulé lors des tests unitaires.

Comme le modèle lui-même MVVM est génial. Mais la bibliothèque de contrôle de WPF fournie avec le support de liaison de données NET 4.0 est très limitée, beaucoup mieux que WinForm, mais cela ne suffit pas pour le MVVM pouvant être lié, je dirais que sa puissance représente environ 30% du MVVM.
MVVM pouvant être lié: il s’agit d’une interface utilisateur où ViewModel est câblé avec View uniquement à l’aide d’une liaison de données.
Le modèle MVVM concerne la représentation d’object de ViewState, il ne décrit pas comment vous maintenez la synchronisation entre View et ViewModel, dans WPF, la liaison de données est possible. Et en fait, vous pouvez utiliser le pattern MVVM dans n’importe quel toolkit d’interface supportant les événements \ callbacks, vous pouvez l’utiliser dans WinAPI pure dans WinForms (j’ai fait, et il n’y a pas beaucoup de travail avec les événements \ callbacks), et vous pouvez même l’utiliser dans Text Console, comme réécrire Norton Commander de DoS en utilisant le modèle MVVM.

En bref: MVVM n’est pas inutile, c’est génial. La bibliothèque de contrôle de NET 4.0 WPF est une corbeille.

Voici la preuve de concept simple ViewModel que vous ne pouvez pas lier de manière pure MVVM en utilisant WPF.

 public class PersonsViewModel { public IList PersonList; public IList TableColumns; public IList SelectedPersons; public Person ActivePerson; public ColumnDescription SortedColumn; } 

Vous ne pouvez pas lier les en-têtes de colonne DataGrid de WPF, vous ne pouvez pas lier les lignes sélectionnées, etc., vous le ferez soit en code simple, soit en écrivant 200 lignes de code XAML pour ces 5 lignes de ViewModel les plus simples. Vous ne pouvez qu’imaginer comment les choses se détériorent avec les ViewModels complexes.
Donc, la réponse est simple à moins que vous n’écriviez l’application Hello World, l’utilisation de MVVM pouvant être lié dans WPF est inutile. Vous passerez le plus clair de votre temps à réfléchir au piratage pour vous connecter à ViewModel. La liaison de données est bien mais soyez prêt à revenir aux 70% de temps de l’événement.

J’ai vu le même problème avec de nombreuses implémentations de MVVM en ce qui concerne les dialogs (modaux). Lorsque je regarde les participants du modèle MVVM, j’ai l’impression qu’il manque quelque chose pour créer une application cohérente.

  • View contient les contrôles d’interface graphique spécifiques et définit l’apparence de l’interface utilisateur.
  • ViewModel représente l’état et le comportement de la présentation.
  • Le modèle peut être un object métier de la couche de domaine ou un service fournissant les données nécessaires.

Mais est manquant est:

  • Qui crée les ViewModels?
  • Qui est responsable du stream de travail de l’application?
  • Qui sert d’intermédiaire entre ViewModels lorsqu’ils ont besoin de communiquer entre eux?

Mon approche consiste à introduire un contrôleur (responsable des cas d’utilisation) responsable des points manquants. Comment cela fonctionne peut être vu dans les exemples d’applications WPF Application Framework (WAF) .

Non, ce n’est pas inutile, mais il est difficile d’envelopper la tête même si le motif lui-même est ridiculement simple. Il y a des tonnes de désinformation et de divers groupes qui se battent pour la bonne façon. Je pense qu’avec WPF et Silverlight, vous devez utiliser MVVM ou vous allez trop coder et tenter de résoudre des problèmes dans un nouveau modèle, la «vieille» méthodologie des formulaires de gains qui vous pose des problèmes. Ceci est plus le cas dans Silverlight, car tout est nécessaire pour être asynchrone (des hacks sont possibles, mais vous devez simplement choisir une autre plate-forme).

Je vous suggère de lire cet article Simplifier le TreeView WPF en utilisant le Pattern ViewModel avec soin pour voir comment MVVM peut être correctement implémenté et vous permettre de changer la mentalité de vos formes gagnantes avec la nouvelle façon de penser du MVVM. En bref, lorsque vous voulez que quelque chose soit fait, appliquez d’abord la logique au ViewModel et non à la vue. Vous voulez sélectionner un article? Changer une icône? Ne pas itérer sur les éléments de l’interface utilisateur, il suffit de mettre à jour les propriétés des modèles et de laisser les liaisons de données faire les choses sérieusement.