Bindung an Modell oder ViewModel [geschlossen]

8

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

  • Logikeinheit testbar machen
  • Reduzieren Sie die Redundanz des Codes (Duplizierung bei Bedarf)

2. Sicherheit

  • Das Modell enthält Eigenschaften, die der Benutzer nicht ändern soll
  • Automatische, aber unerwünschte Aktualisierungen können passieren, wenn Sie an Modell
  • binden

3. Lose Kopplung

  • Wenn Sie direkt an das Modell binden, wird eine Verbindung zwischen den unteren Ebenen und View
  • hergestellt
  • Das Ändern des Modells führt zu Änderungen in allen Ansichten
  • Die Ansicht hängt nicht von einem bestimmten Modell ab
  • Modell kann leicht mit EF, einigen DSL, Batch-Dateien, usw. generiert werden

4. Geschwindigkeit der Entwicklung

  • Sie können mit einer Prototype ViewModel Hierarchie beginnen und an diese binden
  • Wenn das Modell noch in Entwicklung ist, können Sie mit 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
  • erstellt werden

5. "Tricky Synchronization" ist gelöst

  • Es gibt viele Lösungen für jedes gegebene "schwierige Synchronisationsproblem", z. B.
  • AutoMapper
  • Ereignissystem aus dem Modell (Modell löst Ereignis aus, ViewModel subskribiert)

6. Gleiche Struktur während des gesamten Projekts

  • Es gibt Punkte, die zu einem ViewModel gehören, wie SelectedItem
  • Das Mischen der Bindung mit Model und ViewModel ist fehlerbehaftet
  • Es ist schwieriger für neue Entwickler, die Struktur des Projekts herauszufinden
  • fängt an, ViewModel später zu holen, wenn es keinen Weg gibt, es ist chaotisch

7. Skalierbarkeit

  • Lässt definieren: Wenn Sie kein ViewModel verwenden, ist es nicht MVVM
  • MVVM kann leicht auf viele Datenquellen, viele Ansichten
  • angewendet werden
  • Wenn Sie Leistungsprobleme feststellen: Lazy loading und caching wird im ViewModel
  • ausgeführt

8. Trennung von Bedenken

  • Die Komplexität in den Griff zu bekommen ist das Hauptproblem in der Software
  • Die alleinige Verantwortung von ViewModels besteht darin, Änderungen vorzunehmen
  • Es ist so einfach, Benachrichtigungen an eine Ansicht zu senden, als sie an einen anderen Prozess oder eine andere Maschine zu senden
  • Das ViewModel, nicht das View-Register für Änderungsbenachrichtigungen für das Modell / die Datenquelle
  • Die Datenquelle kann das Senden von Ereignissen an das ViewModel ignorieren, das die Änderung verursacht hat

Im Gegenteil, der Typ von dem anderen Thread Dumps einige Punkte, einschließlich

  1. 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.

  2. 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.

  3. 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.

  4. 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.

    
Mare Infinitus 05.06.2013, 18:20
quelle

6 Antworten

6

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.

    
Dennis 05.06.2013 18:29
quelle
5
  

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.

    
Reed Copsey 05.06.2013 18:25
quelle
1

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.

    
Eric Dand 05.06.2013 18:49
quelle
1

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.

    
Randolpho 06.06.2013 02:23
quelle
1

Gegenargumente:

  
  1. Logik aus der Ansicht entfernen
  2.   

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.

  
  1. Sicherheit   • Das Modell enthält Eigenschaften, die der Benutzer nicht ändern soll
  2.   

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.

  
  1. Lose Kupplung   • Wenn Sie direkt an das Modell binden, wird eine Verbindung zwischen den unteren Ebenen und View
  2. 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.

  
  1. Geschwindigkeit der Entwicklung
  2.   

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.

  
  1. "Tricky synchronizion" ist gelöst   • Es gibt viele Lösungen für jedes gegebene "schwierige Synchronisierungs" -Problem, z.   • AutoMapper
  2.   

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.

  
  1. Gleiche Struktur während des gesamten Projekts   • Es gibt Punkte, die zu einem ViewModel gehören, wie SelectedItem
  2.   

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.

  
  1. Skalierbarkeit   • Lässt definieren: Wenn Sie kein ViewModel verwenden, ist es nicht MVVM
  2.   

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.

  
  1. Trennung von Bedenken
  2.   

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.

    
Jonathan Allen 05.06.2013 21:57
quelle
0

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%     
Jonathan Allen 05.06.2013 20:24
quelle

Tags und Links