11 Stimmen

MVVM: Thin ViewModels und Rich Models

Ich kämpfe weiterhin mit dem MVVM-Muster und bin bei dem Versuch, ein praktisches Design für ein kleines/mittleres Projekt zu erstellen, auf eine Reihe von Herausforderungen gestoßen. Eine dieser Herausforderungen besteht darin, herauszufinden, wie man die Vorteile der Entkopplung mit diesem Muster nutzen kann, ohne eine Menge sich wiederholenden, schwer zu wartenden Code zu erstellen.

Meine derzeitige Strategie besteht darin, "umfangreiche" Modellklassen zu erstellen. Sie sind sich dessen bewusst, dass sie von einem MVVM-Muster verwendet werden und implementieren INotifyPropertyChanged, erlauben, dass ihre Sammlungen beobachtet werden und sind sich bewusst, dass sie immer beobachtet werden können. Meine ViewModel-Klassen neigen dazu, dünn zu sein, und geben nur dann Eigenschaften preis, wenn Daten tatsächlich transformiert werden müssen, wobei der Großteil ihres Codes aus RelayCommand-Handlern besteht. Views binden sich gerne entweder an ViewModels oder Models direkt, je nachdem, ob eine Datentransformation erforderlich ist. Ich verwende AOP (über Postsharp), um die Schmerzen von INotifyPropertyChanged zu lindern, was es einfach macht, alle meine Model-Klassen auf diese Weise "reich" zu machen.

Gibt es wesentliche Nachteile bei diesem Ansatz? Kann ich davon ausgehen, dass das ViewModel und die View so eng miteinander gekoppelt sind, dass ich, wenn ich eine neue Datentransformation für die View benötige, diese einfach dem ViewModel bei Bedarf hinzufügen kann?

6voto

majocha Punkte 1151

Ich denke, INotifyPropertyChanged auf Ihrem Modell ist nur dann sinnvoll, wenn Sie erwarten, dass es von Ihrer VM und externen "Kräften" gleichzeitig bearbeitet wird.

Ich persönlich bin ein Befürworter der POCO-Modelle. Wenn ich ein rahmenspezifisches Gerüst in mein Modell einbauen würde, würde ich mir Sorgen machen. Wenn Sie ein Ereignis in Ihre Modellklasse einfügen, müssen Sie sorgfältig mögliche Probleme mit dem Lebenszyklus Ihres Modells, der Serialisierung, der Speicherung usw. bedenken. Was passiert zum Beispiel, wenn Sie Ihr Objekt aus der Datenquelle neu erstellen und alte INotifyPropertyChanged-Abonnements nun ungültig sind?

Ein ähnlicher, besserer Platz für ObservableCollection ist in der VM, die eine IEnumerable-Datenquelle verbrauchen und der Ansicht nur ausgewählte oder ad hoc gefilterte Elemente präsentieren kann.

3voto

Bermo Punkte 4901

Ich halte dies für den pragmatischen Ansatz - wir haben dieses Muster in der Vergangenheit erfolgreich verfolgt.

Die grundlegende Prämisse war, direkt an ein Modell zu binden, das INotifyPropertyChanged für die meisten schreibgeschützten Daten implementiert, und dann zusätzliche Eigenschaften zum Viewmodel für anzeigespezifische Dinge hinzuzufügen, die transformiert werden müssen (wie Sie vorgeschlagen haben). Für nicht schreibgeschützte Eigenschaften fanden wir es am einfachsten, Viewmodel-Einträge zu erstellen (in der Regel vom Typ String), da dies eine einfache clientseitige Validierung im Viewmodel ermöglicht.

3voto

vidalsasoon Punkte 4320

Haftungsausschluss - Ich bin kein Experte -

Ich setze INotifyChanged nicht auf meine Models. Ich hatte dies zunächst getan, kam aber zu der einfachen Erkenntnis, dass INotifyChanged wirklich nur für die Benachrichtigung der Benutzeroberfläche praktisch ist, so dass ich jetzt nur INotifyChanged auf meine ViewModels lege. Dies hat es einfacher gemacht, die Anzahl der "RaisePropertyChanged" zu kontrollieren... Meine Views verweisen nie direkt auf ein Model.

Ich arbeite an meinem ersten MVVM-Projekt noch an meinem 3. großen Refactor :P

0voto

Kirk Punkte 4161

Ich stimme zu, dass es eine enge Kopplung zwischen dem View und dem ViewModel geben wird. Aber dies kann bis zu einem gewissen Grad durch die Verwendung von IValueConverters, wann immer möglich, um Transformationen zu tun gemildert werden.

Ich versuche, meine Geschäftslogik in meinem ViewModel zu halten. Außerdem verwende ich das ViewModel, um die Form meines Modells so zu ändern, dass sie zu dem passt, was die Ansicht erwarten könnte.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X