Ich weiß, dass es bereits Fragen zu diesem Thema gibt, aber die Probleme dort sind etwas spezifisch für andere Probleme und bieten keine schlüssigen Antworten.
Besonders die hier: Frage1 , Question2 und natürlich Frage3 also bitte diese Frage nicht zu schnell schließen . Sie antworten dort nur "Mach das, tu das" und nicht warum!
Es gibt Leute da draußen, die die Notwendigkeit eines ViewModel
ablehnen und das sagen
Der "Standard" -Weg besteht darin, direkt an das Model zu binden . Dies leugne ich und versuche es mit technischen Argumenten zu beweisen.
Von meinem Hintergrund in MVC
, MVP
, Presentation Model
ist es nur natürlich
mir ein ViewModel
zu benutzen. Vielleicht vermisse ich einen wichtigen Punkt?
Also ist für mich die Vorgabe, an ein ViewModel
zu binden, egal was Model
ist (und egal, ob es INotifyPropertyChanged
implementiert oder nicht).
Es gibt verschiedene Gründe , die ich für die Bindung an ViewModel
s sehe, einschließlich
(Wie hier erwähnt CodeProject und hier < a href="http://blog.alner.net/archive/2010/02/09/mvvm-to-wrap-or-not-to-wrap-should-viewmodels-wrap.aspx"> zu einem anderen Artikel )
1. Logik aus der Ansicht entfernen
2. Sicherheit
3. Lose Kopplung
4. Geschwindigkeit der Entwicklung
Prototype ViewModel
Hierarchie beginnen und an diese binden Prototype Model
beginnen
Model
und ViewModel
können testdriven entwickelt werden, unabhängig vom View View
kann vollständig von einem Designer oder Entwickler mit starkem Design-Hintergrund 5. "Tricky Synchronization" ist gelöst
6. Gleiche Struktur während des gesamten Projekts
7. Skalierbarkeit
8. Trennung von Bedenken
Im Gegenteil, der Typ von dem anderen Thread Dumps einige Punkte, einschließlich
Wenn das Modell direkt aktualisiert wird, weiß das Ansichtsmodell nicht, dass ein Ereignis mit geänderter Eigenschaft ausgelöst wird. Dies führt dazu, dass die Benutzeroberfläche nicht mehr synchron ist. Dies schränkt die Möglichkeiten zum Senden von Nachrichten zwischen übergeordneten und untergeordneten Ansichtsmodellen stark ein.
Wenn das Modell eine eigene Benachrichtigung über die Änderung der Eigenschaft hat, sind # 1 und 2 kein Problem. Stattdessen müssen Sie sich Gedanken über Speicherlecks machen, wenn die Wrapper-VM den Gültigkeitsbereich verlässt, das Modell jedoch nicht.
Wenn Ihre Modelle komplex sind und viele untergeordnete Objekte enthalten, müssen Sie den gesamten Baum durchlaufen und ein zweites Objektdiagramm erstellen, das das erste schattiert. Dies kann ziemlich mühsam und fehleranfällig sein.
Mit Wrapped Collections ist es besonders schwierig zu arbeiten. Jedes Mal, wenn ein Element (Benutzeroberfläche oder Back-End) ein Element aus einer Sammlung einfügt oder entfernt, muss die Shadow-Sammlung entsprechend aktualisiert werden. Diese Art von Code ist wirklich schwer zu bekommen.
Die Frage ist also: Was ist die Standardmethode zum Binden und warum?
Vermisse ich Punkte, die ein ViewModel erforderlich machen?
Gibt es echte Gründe, die man an ein Modell binden möchte?
Am wichtigsten ist das warum , nicht das How to.
Modelle anzeigen enthält in der Regel Elemente, die mit der Ansicht verwendet werden sollen (z. B. Eigenschaften wie IsSomethingSelected
, IsSomethingExpanded
, IsSomethingVisible
, jede Implementierung von ICommand
).
Siehst du irgendeinen Grund, all diese Sachen in Models zu bringen? Natürlich nicht. Deshalb gibt es Ansichtsmodelle.
Die Frage ist also: Was ist die Standardmethode zum Binden und warum?
Im Allgemeinen würde ich argumentieren, dass das Anwenden eines ViewModels und das Binden daran standardmäßig ist. Es gibt einen Grund, dass "ViewModel" existiert und Teil des MVVM-Patterns ist.
Es gibt andere Gründe, warum ein ViewModel erforderlich ist, außer den reinen Daten. Sie implementieren auch normalerweise anwendungsspezifische Logik (dh: nicht Teil des Modells, aber in der Anwendung erforderlich). Jede ICommand
-Implementierung zum Beispiel sollte wirklich in einem ViewModel sein, da sie völlig nicht mit dem Model verwandt ist.
Gibt es irgendwelche wirklichen Gründe, die man an ein Modell binden möchte?
In einigen Fällen kann es einfacher sein, insbesondere wenn Ihr Modell INotifyPropertyChanged
bereits implementiert. Die Reduzierung der Code-Komplexität ist ein wertvolles Ziel mit eigenen Verdiensten.
Ich stimme Reed zu - das ViewModel ist das, was man binden sollte. Ich stelle mir immer vor, dass das Modell eine mehr oder weniger statische Menge von Werten ist, die sich nicht so häufig oder dynamisch ändern wie das ViewModel. Im Allgemeinen versuche ich alles mit einem Wert zu setzen, der zur Kompilierungszeit im Modell angenommen werden kann, und alles, was zur Laufzeit im ViewModel ermittelt werden würde.
Die Ansicht selbst sollte nicht mehr als die einfachste Logik haben. Der Rest sollte Verweise auf das ViewModel sein. Sicherheit ist manchmal das Problem, aber ich mag es einfach für die Lesbarkeit und Prägnanz des Codes. Es ist viel einfacher, mit Code umzugehen, wenn alle ästhetischen Dinge in der Ansicht gemacht werden, umso mehr mathematische, logische Dinge sind im ViewModel versteckt und alle harten Daten sind in einem separaten Modell.
MVVM ist auch sehr eng verwandt mit MVC , mit dem Leitprinzip, dass sich das Model und die View niemals direkt sehen sollten. Noch einmal, für mich ist es eine Klarheit Sache. Die Logik, die bestimmt, wie sich die Werte des Modells ändern sollten, sollte auch im ViewModel / Controller sein. Die Ansicht sollte nicht für sich selbst denken.
Denken Sie an die Ansicht wie eine Empfangsdame: Es ist ein freundliches Gesicht, das den Benutzer anspricht ("spricht mit"). Das ViewModel ist der Buchhalter im Büro hinter der Tür neben der Rezeption, und das Model ist seine / ihre Sammlung von Nachschlagewerken und Notizen. Wenn der Rezeptionist anfängt, an den Rand der Bücher des Buchhalters zu schreiben, die Notizen des Buchhalters zu löschen und Dinge in den Aufzeichnungen zu ändern, werden die Dinge verwirrend.
Es gibt keine "richtige" Antwort auf Ihre Frage. WPF wird Ihnen natürlich gerne erlauben, sich an das zu binden, was Sie sich selbst als "Modell" -Objekt erklärt haben; das Framework ist einfach egal. Sie müssen nicht immer dem MVVM-Muster folgen, nur weil Sie eine Anwendung in WPF ausführen. Kontext ist immer der Schlüssel zu jeder Software, die Sie schreiben. Wenn Sie Zeit brauchen und einen schnellen Ausgang für Ihren Prototyp benötigen, binden Sie sich auf jeden Fall an das Modell und refaktorieren Sie, wenn es nötig ist.
Ich denke, was Sie wirklich fragen ist "Wann sollte ich das MVVM-Muster verwenden?"
Die Antwort ist natürlich "wenn Ihr Problem zu dem Muster passt".
Was gibt dir das MVVM-Muster? Sie haben bereits einige Gründe für die Verwendung von MVVM aufgelistet, aber das wichtigste für das Muster ist die lose Kopplung - all die anderen sind damit einverstanden.
Der gesamte Punkt des MVVM-Musters besteht darin, sicherzustellen, dass Ihr Modell ein Zustandsautomat ist, der nichts darüber weiß, wie Daten einem Benutzer präsentiert oder von ihm erhalten werden. In gewisser Weise ist Ihr Modell reine Datenstruktur, die in dem für das Modell sinnvollen Format strukturiert ist und nicht in einem für den Menschen sinnvollen Format strukturiert ist. Ihr ViewModel ist verantwortlich für die Übersetzung zwischen dieser reinen Datenplattform (dem Modell) und einer Benutzereingabe-Plattform (der Ansicht). Das ViewModel ist eng mit der View und dem Model gekoppelt, aber das Wichtigste ist, dass das Model nichts von der View kennt.
Gegenargumente:
- Logik aus der Ansicht entfernen
Das Entfernen von Logik aus dem Ansichtsmodell ist ebenfalls nützlich. Indem man Logik wie Validierung, berechnete Felder usw. in das Modell einfügt, bleibt ein leichteres, saubereres Betrachtungsmodell übrig.
• Logikeinheit testbar machen
Das Modell selbst ist sehr einfach zu testen. Sie müssen sich keine Sorgen machen, Bibliotheken zu verspotten und was nicht wie bei einem View-Modell, das sich mit externen Services beschäftigt.
• Reduzieren Sie die Redundanz des Codes (Duplizierung bei Bedarf)
Mehrere Ansichtsmodelle können dasselbe Modell verwenden, wodurch Redundanzen für die Validierung, berechnete Felder usw. reduziert werden.
- Sicherheit • Das Modell enthält Eigenschaften, die der Benutzer nicht ändern soll
Setzen Sie sie dann nicht auf der Benutzeroberfläche ein.
• Automatische, aber unerwünschte Aktualisierungen können passieren, wenn Sie an Modell binden
Nichts davon macht irgendeinen Sinn. Wenn Ihre VM nur ein Wrapper um Ihr Modell ist, werden diese Updates nur heruntergefahren.
- Lose Kupplung • Wenn Sie direkt an das Modell binden, wird eine Verbindung zwischen den unteren Ebenen und View
hergestellt
Diese Kopplung verschwindet nicht auf magische Weise, wenn Sie eine Wrapper-VM zwischen sie schieben.
• Das Ändern des Modells verursacht Änderungen in allen Ansichten
Durch das Ändern des Modells werden Änderungen in allen Wrapper-Ansichtsmodellen verursacht. Das Ändern des Ansichtsmodells führt auch zu Änderungen in allen Ansichten. Daher kann das Modell weiterhin Änderungen in allen Ansichten verursachen.
• Die Ansicht hängt nicht von einem bestimmten Modell ab
Das ist wahr mit oder ohne das Ansichtsmodell, das das Modell umhüllt. Es sieht nur Eigenschaften, nicht tatsächliche Klassen.
• Modell kann leicht mit EF, einigen DSL, Batch-Dateien, usw. erstellt werden
Ja. Und mit ein bisschen Arbeit können diese einfach generierten Modelle nützliche Schnittstellen wie INotifyDataErrorInfo, IChangeTracking und IEditableObject enthalten.
- Geschwindigkeit der Entwicklung
Die Bindung an Modelle bietet eine schnellere Entwicklung, da Sie nicht alle Eigenschaften zuordnen müssen.
• Sie können mit einer Prototyp-ViewModel-Hierarchie beginnen und an diese binden
Oder ich kann mit einem Prototyp beginnen. Durch das Hinzufügen eines Wrappers wird nichts gewonnen.
• Wenn sich das Modell noch in der Entwicklung befindet, können Sie mit einem Prototypmodell beginnen • Model und ViewModel können testdriviert entwickelt werden, unabhängig vom View
Auch hier wird nichts erreicht, wenn ein Wrapper um das Modell hinzugefügt wird.
• Die Ansicht kann vollständig von einem Designer oder Entwickler mit starkem Designhintergrund erstellt werden.
Auch hier wird nichts erreicht, wenn ein Wrapper um das Modell hinzugefügt wird.
- "Tricky synchronizion" ist gelöst • Es gibt viele Lösungen für jedes gegebene "schwierige Synchronisierungs" -Problem, z. • AutoMapper
Wenn Sie Autoadapter verwenden, um die Daten in das Ansichtsmodell zu kopieren, verwenden Sie nicht das MVVM-Muster. Sie verwenden nur Ansichten und Modelle.
• Ereignissystem aus dem Modell (Modell löst Ereignis aus, ViewModel abonniert)
Hallo Speicherlecks. Das heißt, es sei denn, Sie sind unglaublich vorsichtig und verzichten auf die Möglichkeit, ein Modell über mehrere Ansichten hinweg zu teilen.
- Gleiche Struktur während des gesamten Projekts • Es gibt Punkte, die zu einem ViewModel gehören, wie SelectedItem
Irrelevant. Niemand argumentiert gegen Nicht-Wrapper-View-Modelle.
• Das Mischen der Bindung zu Model und ViewModel ist fehlerbehaftet
Nicht unterstützt.
• Es ist schwieriger für neue Entwickler, die Struktur des Projekts herauszufinden
Nicht unterstützt.
• ViewModel später zu starten, wenn es keinen Weg gibt, ist chaotisch
Irrelevant. Wieder einmal streitet sich niemand gegen die Verwendung von Nicht-Wrapper View-Modellen.
- Skalierbarkeit • Lässt definieren: Wenn Sie kein ViewModel verwenden, ist es nicht MVVM
Irrelevant. Zum dritten Mal streitet sich niemand gegen die Verwendung von Nicht-Wrapper-View-Modellen.
• MVVM kann leicht auf viele Datenquellen angewendet werden, viele Ansichten
Irrelevant. Wir streiten nicht darüber, ob wir MVVM benutzen oder nicht, wir streiten darüber, wie man es am besten benutzt.
• Wenn Sie Leistungsprobleme feststellen: Lazy Loading und Caching gehen in das ViewModel
Einverstanden, aber irrelevant.Niemand schlägt vor, Serviceaufrufe in das Modell zu schieben.
- Trennung von Bedenken
Hier ist das Wrapper View-Modell am schwersten.
Das Ansichtsmodell muss sich bereits mit UI-Daten (z. B. Modi, ausgewählten Elementen) befassen und die ICommands hosten, die externe Dienste aufrufen.
Das Verschieben aller Modelldaten, der Validierungslogik, der berechneten Eigenschaften usw. in das View-Modell ist noch aufgeblähter.
Hier ist ein einfacher Objektgraph. Nur ein paar wirklich einfache Modelle mit normalen Eigenschaftenänderung und Validierungsereignissen.
Diejenigen unter Ihnen, die denken, dass Modelle in Ansichtsmodelle verpackt werden müssen, zeigen Ihren Code.
%Vor%Und hier ist ein typisches ViewModel, das dazu passen würde:
%Vor%