Ist eine orthodoxe MVVM-Implementierung sinnlos? Ich erstelle eine neue Anwendung und habe Windows Forms und WPF in Betracht gezogen. Ich habe mich für WPF entschieden, weil es zukunftssicher ist und viel Flexibilität bietet. Es gibt weniger Code und es ist einfacher, mithilfe von XAML wesentliche Änderungen an Ihrer Benutzeroberfläche vorzunehmen.
Da die Wahl für WPF offensichtlich ist, habe ich mir gedacht, dass ich MVVM genauso gut als meine Anwendungsarchitektur verwenden kann, da es Mischbarkeit, Trennungsprobleme und Testbarkeit von Einheiten bietet. Theoretisch scheint es schön wie der heilige Gral der UI-Programmierung. Dieses kurze Abenteuer; hat sich jedoch zu echten Kopfschmerzen entwickelt. Wie in der Praxis erwartet, habe ich festgestellt, dass ich ein Problem gegen ein anderes getauscht habe. Ich neige dazu, ein besessener Programmierer zu sein, weil ich die Dinge richtig machen möchte, damit ich die richtigen Ergebnisse erzielen und möglicherweise ein besserer Programmierer werden kann. Das MVVM-Muster hat meinen Produktivitätstest gerade nicht bestanden und ist gerade zu einem großen Glücksfall geworden!
Das klare Beispiel ist das Hinzufügen von Unterstützung für ein modales Dialogfeld. Der richtige Weg ist, ein Dialogfeld einzurichten und es an ein Ansichtsmodell zu binden. Es ist schwierig, dies zum Laufen zu bringen. Um vom MVVM-Muster zu profitieren, müssen Sie Code an mehreren Stellen in den Ebenen Ihrer Anwendung verteilen. Sie müssen auch esoterische Programmierkonstrukte wie Vorlagen und Lamba-Ausdrücke verwenden. Dinge, bei denen Sie auf den Bildschirm starren und sich am Kopf kratzen. Dies macht Wartung und Debugging zu einem Albtraum, der darauf wartet, passiert zu werden, wie ich kürzlich herausgefunden habe. Ich hatte ein About-Feld, das einwandfrei funktionierte, bis ich beim zweiten Aufruf eine Ausnahme bekam, die besagte, dass das Dialogfeld nach dem Schließen nicht mehr angezeigt werden konnte. Ich musste dem Dialogfenster einen Ereignishandler für die Schließfunktion hinzufügen. eine weitere in der IDialogView-Implementierung und schließlich eine weitere im IDialogViewModel. Ich dachte, MVVM würde uns vor solch extravagantem Hackery retten!
Es gibt mehrere Leute mit konkurrierenden Lösungen für dieses Problem und sie sind alle Hacks und bieten keine saubere, leicht wiederverwendbare, elegante Lösung. Die meisten MVVM-Toolkits beschönigen Dialoge, und wenn sie diese ansprechen, handelt es sich lediglich um Warnfelder, für die keine benutzerdefinierten Schnittstellen oder Ansichtsmodelle erforderlich sind.
Ich habe vor, das MVVM-Ansichtsmuster aufzugeben, zumindest seine orthodoxe Implementierung. Was denken Sie? Hat sich die Mühe für Sie gelohnt, wenn Sie welche hatten? Bin ich nur ein inkompetenter Programmierer oder ist MVVM nicht das, worauf es ankommt?
Antworten:
Tut mir leid, wenn meine Antwort etwas länger wurde, aber beschuldigen Sie mich nicht! Ihre Frage ist ebenfalls lang.
Zusammenfassend ist MVVM nicht sinnlos.
Ja, das ist es wirklich.
MVVM bietet Ihnen jedoch eine Möglichkeit, das Erscheinungsbild der Benutzeroberfläche von der Logik zu trennen. Niemand zwingt Sie, es überall zu verwenden, und niemand hält eine Waffe gegen Ihre Stirn, damit Sie für alles ein separates ViewModel erstellen.
Hier ist meine Lösung für dieses spezielle Beispiel:
Wie die Benutzeroberfläche mit einer bestimmten Eingabe umgeht, geht das ViewModel nichts an. Ich würde der .xaml.cs-Datei der Ansicht Code hinzufügen, der das Dialogfeld instanziiert und dieselbe ViewModel-Instanz (oder bei Bedarf etwas anderes) wie ihren DataContext festlegt.
Nun, Sie müssen es nicht an mehreren Stellen verwenden. So würde ich es lösen:
Ich denke, dass der Zweck von MVVM in erster Linie darin besteht, die Logik der Anwendung von der konkreten Benutzeroberfläche zu trennen und somit einfache Änderungen (oder einen vollständigen Austausch) der Benutzeroberfläche zu ermöglichen.
Ich verwende das folgende Prinzip: Die Ansicht kann vom ViewModel alles wissen und annehmen, was sie will, aber das ViewModel kann NICHTS über die Ansicht wissen.
WPF bietet ein schönes Bindungsmodell, mit dem Sie genau das erreichen können.
(Übrigens sind Vorlagen und Lambda-Ausdrücke nicht esoterisch, wenn sie richtig verwendet werden. Aber wenn Sie nicht möchten, verwenden Sie sie nicht.)
Ja, ich kenne das Gefühl. Genau das, was ich fühlte, als ich MVVM zum ersten Mal sah. Aber sobald Sie den Dreh raus haben, wird es sich nicht mehr schlecht anfühlen.
Warum sollten Sie ein ViewModel hinter eine About-Box stellen? Das hat keinen Sinn.
Ja, denn die Tatsache, dass sich ein UI-Element im selben Fenster oder in einem anderen Fenster befindet oder derzeit den Mars umkreist, ist für ViewModels kein Problem.
Trennung von Bedenken
BEARBEITEN:
Hier ist ein sehr schönes Video mit dem Titel Build your own MVVM Framework . Es ist sehenswert.
quelle
Für ein alltägliches modales Dialogfeld? Sie machen dort sicherlich etwas falsch - die MVVM-Implementierung muss nicht so komplex sein.
Wenn man bedenkt, dass Sie sowohl für MVVM als auch für WPF neu sind, verwenden Sie wahrscheinlich überall suboptimale Lösungen und erschweren die Dinge unnötig - zumindest habe ich dies getan, als ich zum ersten Mal bei WPF war. Stellen Sie sicher, dass das Problem wirklich MVVM und nicht Ihre Implementierung ist, bevor Sie aufgeben.
MVVM, MVC, Document-View usw. sind eine alte Musterfamilie. Es gibt Nachteile, aber keine schwerwiegenden Mängel der von Ihnen beschriebenen Art.
quelle
Ich bin mitten in einer recht komplexen MVVM-Entwicklung mit PRISM, daher musste ich mich bereits mit solchen Problemen auseinandersetzen.
Meine persönlichen Schlussfolgerungen:
MVVM gegen MVC / PopUps & Co.
quelle
Ich beschäftige mich mit dem Problem der Dialoge durch Betrug. Mein MainWindow implementiert eine IWindowServices-Schnittstelle, die alle anwendungsspezifischen Dialoge verfügbar macht. Meine anderen ViewModels können dann die Dienstschnittstelle importieren (ich verwende MEF, aber Sie können die Schnittstelle einfach manuell über Konstruktoren übergeben) und damit das Notwendige erreichen. Hier ist zum Beispiel, wie die Benutzeroberfläche für eine kleine Dienstprogrammanwendung von mir aussieht:
Dadurch werden alle Dialogausführungen an einem Ort gespeichert und können für Unit-Tests problemlos entfernt werden. Ich folge dem Muster, dass der Client des Dialogfelds das entsprechende ViewModel erstellen muss, das er dann nach Bedarf konfigurieren kann. Die Aufrufblöcke ausführen und anschließend kann der Client den Inhalt des ViewModel anzeigen, um die Dialogergebnisse anzuzeigen.
Ein "reineres" MVVM-Design mag für eine große Anwendung wichtig sein, bei der Sie eine sauberere Isolierung und eine komplexere Zusammensetzung benötigen. Für kleine bis mittelgroße Apps halte ich jedoch einen praktischen Ansatz mit geeigneten Diensten zum Freilegen der erforderlichen Haken für ausreichend .
quelle
Designmuster sollen Ihnen helfen, nicht behindern. Ein kleiner Teil davon, ein guter Entwickler zu sein, besteht darin, zu wissen, wann man "gegen die Regeln verstößt". Wenn MVVM für eine Aufgabe umständlich ist und Sie festgestellt haben, dass der zukünftige Wert die Mühe nicht wert ist, verwenden Sie das Muster nicht. Zum Beispiel, wie andere Poster kommentiert haben, warum sollten Sie den gesamten Aufwand durchlaufen, um eine einfache About-Box zu implementieren?
Designmuster sollten niemals dogmatisch befolgt werden.
quelle
Da das Muster selbst MVVM ist großartig. Die mit NET 4.0-Datenbindungsunterstützung gelieferte Steuerungsbibliothek von WPF ist jedoch sehr begrenzt. Sie ist viel besser als WinForm, reicht jedoch nicht für bindbare MVVM aus. Ich würde sagen, dass die Leistung etwa 30% der für bindbare MVVM erforderlichen Leistung beträgt.
Bindbares MVVM: In dieser Benutzeroberfläche wird ViewModel nur mithilfe der Datenbindung mit View verbunden.
Das MVVM-Muster bezieht sich auf die Objektdarstellung des ViewState. Es beschreibt nicht, wie Sie die Synchronisierung zwischen View und ViewModel aufrechterhalten. In WPF ist es Datenbindung, aber es kann alles sein. Und tatsächlich können Sie MVVM-Muster in jedem UI-Toolkit verwenden, das Ereignisse \ Rückrufe unterstützt. Sie können es in reinem WinAPI in WinForms verwenden (ich habe es getan, und es funktioniert nicht viel mehr mit Ereignissen \ Rückrufen), und Sie können es sogar in Text verwenden Konsole, wie das Umschreiben von Norton Commander von DoS mithilfe des MVVM-Musters.
Kurzum: MVVM ist nicht sinnlos, es ist großartig. Die Steuerungsbibliothek von NET 4.0 WPF ist Papierkorb.
Hier ist das einfache Proof-of-Concept-ViewModel, mit dem Sie mit WPF keine Daten in reiner MVVM-Weise binden können.
Sie können die DataGrid-Spaltenüberschriften von WPF nicht an Daten binden, Sie können ausgewählte Zeilen usw. nicht an Daten binden usw. Sie werden dies entweder auf einfache Weise im Code tun oder 200 Zeilen XAML-Hack-Code für diese 5 Zeilen des einfachsten ViewModel schreiben. Sie können sich nur vorstellen, wie es mit komplexen ViewModels schlimmer wird.
Die Antwort ist also einfach, es sei denn, Sie schreiben eine Hello World-Anwendung. Die Verwendung von bindbarem MVVM in WPF ist sinnlos. Sie werden die meiste Zeit damit verbringen, über Hack nachzudenken, um Ihr ViewModel zu binden. Die Datenbindung ist nett, aber seien Sie bereit, auf 70% der Zeit zurückzugreifen.
quelle
Nein, es ist nicht sinnlos, aber es ist schwierig, den Kopf herumzureißen, obwohl das Muster selbst lächerlich einfach ist. Es gibt Unmengen von Fehlinformationen und verschiedene Gruppen, die um den richtigen Weg kämpfen. Ich denke, mit WPF und Silverlight sollten Sie MVVM verwenden, sonst sind Sie überfordert, die „alte“ Win-Forms-Methode zu codieren und zu versuchen, Probleme in einem neuen Modell zu lösen, was Sie nur in Schwierigkeiten bringt. Dies ist in Silverlight eher der Fall, da alles asynchron sein muss (Hacks sind möglich, aber Sie sollten einfach eine andere Plattform auswählen).
Ich würde empfehlen, diesen Artikel zu lesen. Vereinfachen Sie die WPF-Baumansicht, indem Sie das ViewModel-Muster sorgfältig verwenden, um zu sehen, wie MVVM gut implementiert werden kann, und um es Ihnen zu ermöglichen, die Mentalität Ihrer Gewinnformen auf die neue Denkweise in MVVM umzustellen. Kurz gesagt, wenn Sie etwas erledigen möchten, wenden Sie die Logik zuerst auf das ViewModel an, nicht auf die Ansicht. Sie möchten einen Artikel auswählen? Ein Symbol ändern? Iterieren Sie nicht über UI-Elemente, sondern aktualisieren Sie einfach die Modelleigenschaften und lassen Sie die Datenbindung das Wesentliche tun.
quelle
Ich habe das gleiche Problem bei vielen MVVM-Implementierungen gesehen, wenn es um (modale) Dialoge geht. Wenn ich mir die Teilnehmer des MVVM-Musters ansehe, habe ich das Gefühl, dass etwas fehlt, um eine kohärente Anwendung zu erstellen.
Aber es fehlt:
Mein Ansatz ist es, einen (Anwendungsfall-) Controller einzuführen, der für die fehlenden Punkte verantwortlich ist. Wie dies funktioniert, können Sie den Beispielanwendungen des WPF Application Framework (WAF) entnehmen.
quelle