it-swarm.com.de

Was ist der Unterschied zwischen MVC und MVVM?

Gibt es einen Unterschied zwischen dem Standardmuster "Model View Controller" und dem Microsoft-Muster "Model/View/ViewModel"?

1248
Bjorn Reppen

MVC/MVVM ist keine entweder/oder Wahl.

Die beiden Muster treten in der ASP.Net- und der Silverlight/WPF-Entwicklung auf unterschiedliche Weise auf.

Für ASP.Net wird MVVM verwendet, um bidirektionale Bindung Daten in Ansichten zu binden. Dies ist normalerweise eine clientseitige Implementierung (z. B. mit Knockout.js). MVC hingegen ist eine Möglichkeit, die Bedenken zu trennen auf der Serverseite .

Für Silverlight und WPF ist das MVVM-Muster umfassender und kann scheinen als Ersatz für MVC (oder andere Muster zum Organisieren von Software in getrennten Verantwortlichkeiten) dienen. Eine Annahme, die häufig aus diesem Muster hervorging, war, dass ViewModel einfach den Controller in MVC ersetzte (als ob Sie VM für C im Akronym ersetzen könnten und alles wäre vergeben) ...

Das ViewModel ersetzt nicht notwendigerweise die Notwendigkeit für separate Controller.

Das Problem ist, dass ein Ansichtsmodell keine Ahnung hat, welche Ansicht es anzeigt, um unabhängig testbar zu sein * und insbesondere bei Bedarf wiederverwendbar zu sein, aber was noch wichtiger ist: keine Ahnung, woher seine Daten kommen .

* Hinweis: In der Praxis entfernen Controller den größten Teil der Logik aus dem ViewModel, für die ein Komponententest erforderlich ist. Die VM wird dann zu einem dummen Container, der nur wenig, wenn überhaupt, Tests erfordert. Dies ist eine gute Sache, da VM nur eine Brücke zwischen dem Designer und dem Programmierer ist. Sie sollte daher einfach gehalten werden.

Selbst in MVVM enthalten Controller normalerweise die gesamte Verarbeitungslogik und entscheiden, welche Daten in welchen Ansichten mit welchen Ansichtsmodellen angezeigt werden sollen.

Nach dem, was wir bisher gesehen haben, besteht der Hauptvorteil des ViewModel-Musters darin, Code aus XAML-Code-Behind zu entfernen , um die XAML-Bearbeitung zu einer unabhängigeren Aufgabe zu machen . Wir erstellen nach wie vor Controller nach Bedarf, um die Gesamtlogik unserer Anwendungen zu steuern (kein Wortspiel beabsichtigt).

Die grundlegenden MVCVM-Richtlinien, denen wir folgen, sind:

  • Views zeigen eine bestimmte Form von Daten an . Sie haben keine Ahnung, woher die Daten stammen.
  • ViewModels enthalten eine bestimmte Form von Daten und Befehlen , sie wissen nicht, woher die Daten oder der Code stammen oder wie sie angezeigt werden.
  • Modelle enthalten die eigentlichen Daten (verschiedene Kontext-, Speicher- oder andere Methoden)
  • Controller überwachen und veröffentlichen Ereignisse. Controller stellen die Logik bereit, die steuert, welche Daten wo angezeigt werden. Controller stellen dem ViewModel den Befehlscode zur Verfügung, sodass das ViewModel tatsächlich wiederverwendbar ist.

Wir haben auch festgestellt, dass das Sculpture Code-Gen Framework MVVM und ein Prisma ähnliches Muster implementiert UND auch Controller verwendet, um die gesamte Anwendungsfalllogik zu trennen.

Gehen Sie nicht davon aus, dass Controller durch View-Modelle veraltet sind.

Ich habe einen Blog zu diesem Thema gestartet, den ich nach und nach ergänzen werde . Es gibt Probleme beim Kombinieren von MVCVM mit den gängigen Navigationssystemen, da die meisten Navigationssysteme nur Ansichten und VMs verwenden, aber darauf werde ich in späteren Artikeln eingehen.

Ein zusätzlicher Vorteil der Verwendung eines MVCVM-Modells besteht darin, dass nur die Controller-Objekte für die Lebensdauer der Anwendung im Speicher vorhanden sein müssen und die Controller hauptsächlich Code und kleine Statusdaten (dh winzige Daten) enthalten Speicheraufwand). Dies führt zu weniger speicherintensiven Apps als bei Lösungen, bei denen Ansichtsmodelle beibehalten werden müssen, und ist ideal für bestimmte Arten der mobilen Entwicklung (z. B. Windows Mobile mit Silverlight/Prism/MEF). Dies hängt natürlich von der Art der Anwendung ab, da Sie möglicherweise noch die gelegentlich zwischengespeicherten VMs für die Reaktionsfähigkeit beibehalten müssen.

Hinweis: Dieser Beitrag wurde mehrmals bearbeitet und bezog sich nicht speziell auf die gestellte enge Frage. Daher habe ich den ersten Teil so aktualisiert, dass er jetzt auch dies abdeckt. Ein Großteil der Diskussion in den Kommentaren unten bezieht sich nur auf diese Dieser Beitrag befasste sich mit der breiteren Verwendung von MVVM in Silverlight, WPF und ASP.Net und sollte Personen davon abhalten, Controller durch ViewModels zu ersetzen.

659
Gone Coding

Ich denke, der einfachste Weg, um zu verstehen, was diese Akronyme bedeuten sollen, ist, sie für einen Moment zu vergessen. Denken Sie stattdessen an die Software, mit der sie erstellt wurden, an jede einzelne. Es geht wirklich nur um den Unterschied zwischen dem frühen Web und dem Desktop.

Das erste Akronym, MVC, stammt aus dem Internet. (Ja, es war vielleicht schon einmal dort, aber das Web hat es für die Masse der Webentwickler populär gemacht.) Denken Sie an Datenbanken, HTML-Seiten und Code dazwischen. Lassen Sie uns dies ein wenig verfeinern, um zu MVC zu gelangen: Nehmen wir für "database" Datenbank plus Schnittstellencode an. Nehmen wir für "HTML-Seiten" HTML-Vorlagen plus Vorlagenverarbeitungscode an. Nehmen wir für "Code dazwischen" an, dass der Benutzer auf Aktionen klickt, die sich möglicherweise auf die Datenbank auswirken und definitiv eine andere Ansicht anzeigen. Das war's zumindest zum Zwecke dieses Vergleichs.

Behalten wir ein Merkmal dieses Webmaterials bei, nicht wie es heute ist, sondern wie es vor zehn Jahren existierte, als JavaScript ein bescheidener, verabscheuungswürdiger Ärger war, von dem echte Programmierer keine Ahnung hatten: Die HTML-Seite ist im Wesentlichen dumm und passiv . Der Browser ist ein Thin Client oder, wenn Sie so wollen, ein schlechter Client. Es gibt keine Intelligenz im Browser. Regel zum Neuladen ganzer Seiten. Die "Ansicht" wird jedes Mal neu generiert.

Erinnern wir uns, dass dieser Web-Weg, trotz aller Wut, im Vergleich zum Desktop schrecklich rückständig war. Desktop-Apps sind Fat Clients oder Rich Clients, wenn Sie so wollen. (Selbst ein Programm wie Microsoft Word kann als eine Art Client betrachtet werden, als Client für Dokumente.) Sie sind Clients voller Intelligenz, voller Kenntnisse über ihre Daten. Sie sind staatlich. Sie speichern die Daten, die sie verarbeiten, im Speicher. Kein Mist wie ein komplettes Neuladen von Seiten.

Und auf diese reichhaltige Desktop-Art entstand wahrscheinlich das zweite Akronym, MVVM. Lassen Sie sich nicht von den Buchstaben täuschen, denn die C.-Controller sind immer noch da. Sie müssen sein. Nichts wird entfernt. Wir fügen nur eine Sache hinzu: Statefulness, Daten, die auf dem Client zwischengespeichert sind (und zusammen mit der Intelligenz, mit diesen Daten umzugehen). Diese Daten, im Wesentlichen ein Cache auf dem Client, werden jetzt "ViewModel" genannt. Dies ermöglicht eine reichhaltige Interaktivität. Und das ist es.

  • MVC = Modell, Steuerung, Ansicht = im Wesentlichen Einwegkommunikation = schlechte Interaktivität
  • MVVM = Modell, Controller, Cache, Ansicht = bidirektionale Kommunikation = umfassende Interaktivität

Wir können sehen, dass das Web mit Flash, Silverlight und vor allem JavaScript MVVM unterstützt. Browser können nicht mehr als Thin Clients bezeichnet werden. Schauen Sie sich ihre Programmierbarkeit an. Sehen Sie sich ihren Speicherverbrauch an. Sehen Sie sich die gesamte Javascript-Interaktivität auf modernen Webseiten an.

Persönlich finde ich diese Theorie und Abkürzung leichter verständlich, wenn ich mir anschaue, worauf sie sich in der konkreten Realität beziehen. Abstrakte Konzepte sind nützlich, insbesondere wenn sie an konkreten Themen demonstriert werden, damit sich der Kreis schließt.

256
Lumi

MVVM Model-View ViewModel ähnelt MVC, Model-View Controller

Der Controller wird durch ein ViewModel ersetzt. Das ViewModel befindet sich unterhalb des UI-Layers. Das ViewModel macht die Daten- und Befehlsobjekte verfügbar, die die Ansicht benötigt. Sie können sich dies als ein Containerobjekt vorstellen, aus dem die Ansicht ihre Daten und Aktionen abruft. Das ViewModel bezieht seine Daten aus dem Modell.

Russel East führt ein Blog durch, in dem mehr Details besprochen werden Warum ist MVVM anders als MVC?)

173
TStamper

Zum einen ist MVVM eine Weiterentwicklung des MVC-Musters, bei dem XAML für die Anzeige verwendet wird. Dieser Artikel skizziert einige der Facetten der beiden.

Der Hauptschwerpunkt der Model/View/ViewModel-Architektur scheint darin zu liegen, dass neben den Daten ("das Modell") eine weitere Schicht nicht-visueller Komponenten ("das ViewModel") vorhanden ist, die die Konzepte der Daten genauer abbilden auf die Konzepte der Ansicht der Daten ("die Ansicht"). Es ist das ViewModel, an das sich die Ansicht bindet, und nicht direkt das Modell.

88
Chris Ballance

Microsoft lieferte eine Erklärung des MVVM-Musters in der Windows-Umgebung hier .

Hier ist ein entscheidender Abschnitt:

Im Entwurfsmuster "Model-View-ViewModel" besteht eine App aus drei allgemeinen Komponenten. enter image description here

  • Modell : Dies ist das Datenmodell, das Ihre App verwendet. In einer Bilderfreigabe-App kann diese Ebene beispielsweise die auf einem Gerät verfügbaren Bilder und die API darstellen, die zum Lesen und Schreiben in die Bildbibliothek verwendet wird.

  • Ansicht : Eine App besteht normalerweise aus mehreren Seiten der Benutzeroberfläche. Jede Seite, die dem Benutzer angezeigt wird, ist eine Ansicht in MVVM-Terminologie. Die Ansicht ist der XAML-Code, mit dem definiert und gestaltet wird, was der Benutzer sieht. Die Daten aus dem Modell werden dem Benutzer angezeigt, und es ist Aufgabe des ViewModel, diese Daten basierend auf dem aktuellen Status der App an die Benutzeroberfläche weiterzuleiten. In einer Bilderfreigabe-App sind die Ansichten beispielsweise die Benutzeroberfläche, die dem Benutzer die Liste der Alben auf dem Gerät, die Bilder in einem Album und möglicherweise eine andere, die dem Benutzer ein bestimmtes Bild zeigt.

  • ViewModel : Das ViewModel bindet das Datenmodell oder einfach das Modell an die Benutzeroberfläche oder die Ansichten der App. Es enthält die Logik zum Verwalten der Daten aus dem Modell und macht die Daten als eine Reihe von Eigenschaften verfügbar, an die die XAML-Benutzeroberfläche oder -Ansichten gebunden werden können. In einer App für die gemeinsame Nutzung von Bildern zeigt das ViewModel beispielsweise eine Liste von Alben und für jedes Album eine Liste von Bildern an. Die Benutzeroberfläche ist unabhängig davon, woher die Bilder kommen und wie sie abgerufen werden. Es kennt einfach eine Reihe von Bildern, die vom ViewModel angezeigt werden, und zeigt sie dem Benutzer an.

48
Mat

Ich dachte, einer der Hauptunterschiede ist, dass in MVC Ihr V Ihr M direkt liest und über das C die Daten manipuliert, während in MVVM Ihr VM als M-Proxy fungiert Bereitstellung der verfügbaren Funktionalität für Sie V.

Wenn ich nicht voll mit Junk bin, wundert es mich, dass niemand einen Hybrid erstellt hat, bei dem Ihr VM lediglich ein M-Proxy ist und C alle Funktionen bietet.

42
George R

Einfacher Unterschied: (Inspiriert von Yaakovs Coursera AngularJS-Kurs)

enter image description here

MVC (Model View Controller)

  1. Modelle: Modelle enthalten Dateninformationen. Ruft Controller und View nicht auf oder verwendet sie nicht. Enthält die Geschäftslogik und Möglichkeiten zur Darstellung von Daten. Einige dieser Daten können in irgendeiner Form in der Ansicht angezeigt werden. Es kann auch eine Logik zum Abrufen der Daten von einer Quelle enthalten.
  2. Controller: Dient als Verbindung zwischen Ansicht und Modell. Aufrufe anzeigen Controller und Controller rufen das Modell auf. Es informiert im Wesentlichen das Modell und/oder die Ansicht, die bei Bedarf geändert werden sollen.
  3. Ansicht: Befasst sich mit UI-Teil. Interagiert mit dem Benutzer.

MVVM (Modellansicht Modell anzeigen)

ViewModel :

  1. Es ist die Darstellung des Zustands der Ansicht.
  2. Es enthält die Daten, die in der Ansicht angezeigt werden.
  3. Reagiert auf das Anzeigen von Ereignissen, auch Präsentationslogik genannt.
  4. Ruft andere Funktionen für die Geschäftslogikverarbeitung auf.
  5. Bittet die Ansicht niemals direkt, etwas anzuzeigen.
21
Pritam Banerjee

MVC ist eine kontrollierte Umgebung und MVVM ist eine reaktive Umgebung.

In einer kontrollierten Umgebung sollten Sie weniger Code und eine gemeinsame Logikquelle haben. die sollte immer in der Steuerung leben. Jedoch; In der Web-Welt wird MVC leicht in Ansichtserstellungslogik und dynamische Ansichtslogik unterteilt. Die Schöpfung lebt auf dem Server und die Dynamik auf dem Client. Sie sehen dies häufig bei ASP.NET MVC in Kombination mit AngularJS, während der Server eine Ansicht erstellt, ein Modell übergibt und an den Client sendet. Der Client interagiert dann mit der Ansicht. In diesem Fall tritt AngularJS als lokaler Controller ein. Nach der Übermittlung wird das Modell oder ein neues Modell an den Server-Controller zurückgegeben und verarbeitet. (Somit geht der Zyklus weiter und es gibt viele andere Übersetzungen dieser Behandlung, wenn mit Sockets oder AJAX usw. gearbeitet wird, aber die gesamte Architektur ist identisch.)

MVVM ist eine reaktive Umgebung, dh Sie schreiben in der Regel Code (z. B. Trigger), der je nach Ereignis aktiviert wird. In XAML, wo MVVM erfolgreich ist, ist dies alles mit dem eingebauten Datenbindungs-Framework möglich, ABER wie erwähnt funktioniert dies auf jedem System in jeder Ansicht mit jeder Programmiersprache. Es ist nicht MS-spezifisch. Das ViewModel wird ausgelöst (normalerweise ein Ereignis mit geänderten Eigenschaften) und die View reagiert darauf basierend auf den von Ihnen erstellten Auslösern. Dies kann technisch werden, aber das Fazit ist, dass die Ansicht zustandslos und ohne Logik ist. Der Status wird einfach basierend auf den Werten geändert. Darüber hinaus sind ViewModels zustandslos mit sehr wenig Logik, und Models sind der Zustand mit im Wesentlichen Null-Logik, da sie nur den Zustand beibehalten sollten. Ich beschreibe dies als Anwendungsstatus (Modell), Statusübersetzer (ViewModel) und dann als visuellen Status/Interaktion (View).

In einer MVC-Desktop- oder clientseitigen Anwendung sollte ein Modell vorhanden sein und das Modell vom Controller verwendet werden. Basierend auf dem Modell ändert der Controller die Ansicht. Ansichten sind normalerweise an Controller mit Schnittstellen gebunden, sodass der Controller mit einer Vielzahl von Ansichten arbeiten kann. In ASP.NET ist die Logik für MVC auf dem Server leicht rückwärts gerichtet, da der Controller die Modelle verwaltet und die Modelle an eine ausgewählte Ansicht übergibt. Die Ansicht wird dann basierend auf dem Modell mit Daten gefüllt und verfügt über eine eigene Logik (normalerweise eine andere MVC-Gruppe, wie sie mit AngularJS erstellt wird). Die Leute werden sich streiten und dies mit der Anwendung MVC verwechseln und versuchen, beides zu tun. An diesem Punkt wird die Wartung des Projekts schließlich zu einer Katastrophe. Stellen Sie bei Verwendung von MVC die Logik und Steuerung IMMER an einem Ort auf. Schreiben Sie KEINE View-Logik in den Code hinter der View (oder in die View über JS for Web), um Controller- oder Modelldaten aufzunehmen. Lassen Sie den Controller die Ansicht ändern. Die EINZIGE Logik, die in einer Ansicht vorhanden sein sollte, ist alles, was zum Erstellen und Ausführen über die verwendete Schnittstelle erforderlich ist. Ein Beispiel hierfür ist das Senden eines Benutzernamens und eines Kennworts. Unabhängig davon, ob auf dem Desktop oder auf der Webseite (auf dem Client) der Controller den Übermittlungsprozess ausführen soll, wenn die Ansicht die Übermittlungsaktion auslöst. Bei richtiger Ausführung können Sie sich jederzeit problemlos in einem MVC-Web oder einer lokalen App zurechtfinden.

MVVM ist persönlich mein Favorit, da es völlig reaktiv ist. Wenn ein Model den Status ändert, lauscht und übersetzt ViewModel diesen Status und das war's !!! Die Ansicht überwacht dann das ViewModel auf Statusänderungen und wird auch basierend auf der Übersetzung aus dem ViewModel aktualisiert. Einige Leute nennen es reine MVVM, aber es gibt wirklich nur eine, und es ist mir egal, wie Sie darüber argumentieren, und es ist immer reine MVVM, in der die Ansicht absolut keine Logik enthält.

Hier ist ein kleines Beispiel: Nehmen wir an, Sie möchten bei einem Tastendruck ein Menü einfügen. In MVC haben Sie eine MenuPressed-Aktion in Ihrer Benutzeroberfläche. Der Controller erkennt, wenn Sie auf die Menüschaltfläche klicken und die Ansicht anweisen, auf der Grundlage einer anderen Schnittstellenmethode wie SlideMenuIn im Menü zu gleiten. Eine Rundreise aus welchem ​​Grund? In dem Fall, dass der Controller entscheidet, dass Sie nichts anderes tun können oder wollen, ist dies der Grund. Der Controller sollte für die Ansicht verantwortlich sein, wobei die Ansicht nichts tut, es sei denn, der Controller sagt dies. JEDOCH; In MVVM sollte das Folienmenü in der Animation integriert und generisch sein, und anstatt angewiesen zu werden, es einzublenden, wird dies basierend auf einem bestimmten Wert ausgeführt. Also hört es sich das ViewModel an und wenn das ViewModel sagt, IsMenuActive = true (oder wie auch immer), findet die Animation dafür statt. Nachdem dies gesagt wurde, möchte ich einen weiteren Punkt WIRKLICH KLAR machen und BITTE darauf achten. IsMenuActive ist wahrscheinlich ein schlechtes MVVM- oder ViewModel-Design. Wenn Sie ein ViewModel entwerfen, sollten Sie niemals davon ausgehen, dass eine View überhaupt über Funktionen verfügt, und nur den übersetzten Modellstatus übergeben. Auf diese Weise ist es dem ViewModel egal, ob Sie Ihre Ansicht ändern, um das Menü zu entfernen und die Daten/Optionen auf eine andere Weise anzuzeigen. Wie würden Sie das Menü verwalten? Wenn die Daten Sinn machen, ist das so. Eine Möglichkeit, dies zu tun, besteht darin, dem Menü eine Liste von Optionen zuzuweisen (wahrscheinlich ein Array von inneren ViewModels). Wenn diese Liste Daten enthält, kann das Menü über den Auslöser geöffnet werden. Wenn nicht, kann es über den Auslöser ausgeblendet werden. Sie haben einfach Daten für das Menü oder nicht im ViewModel. Entscheiden Sie sich NICHT, diese Daten im ViewModel anzuzeigen/auszublenden. Übersetzen Sie einfach den Status des Modells. Auf diese Weise ist die Ansicht vollständig reaktiv und allgemein und kann in vielen verschiedenen Situationen verwendet werden.

All dies macht wahrscheinlich überhaupt keinen Sinn, wenn Sie nicht bereits ein wenig mit der Architektur der einzelnen Systeme vertraut sind und wissen, dass es sehr verwirrend sein kann, wenn Sie VIELE SCHLECHTE Informationen im Internet finden.

Also ... Dinge zu beachten, um dies richtig zu machen. Überlegen Sie sich im Voraus, wie Sie Ihre Anwendung gestalten möchten, und halten Sie sich an sie.

Wenn Sie MVC verwenden, was großartig ist, stellen Sie sicher, dass Sie den Controller verwalten können und die volle Kontrolle über Ihre Ansicht haben. Wenn Sie eine große Ansicht haben, sollten Sie der Ansicht Steuerelemente hinzufügen, die unterschiedliche Steuerelemente haben. Kaskadieren Sie diese Controller NICHT mit anderen Controllern. Sehr frustrierend zu pflegen. Nehmen Sie sich einen Moment Zeit und gestalten Sie die Dinge so, dass sie als separate Komponenten funktionieren. Lassen Sie den Controller das Modell immer anweisen, den Speicher festzuschreiben oder fortzusetzen. Die ideale Abhängigkeitseinstellung für MVC in ist Ansicht ← Controller → Modell oder mit ASP.NET (fangen Sie nicht an) Modell ← Ansicht ↔ Controller → Modell (wobei Modell das sein kann) Das gleiche oder ein völlig anderes Modell von Controller zu View) ... Natürlich müssen Sie an dieser Stelle nur wissen, wo ein Modell zurückgegeben werden soll, wenn Sie auf den Endpunkt verweisen möchten.

Wenn Sie MVVM machen, segne ich Ihre gütige Seele, aber nehmen Sie sich die Zeit, es RICHTIG zu machen! Verwenden Sie keine Schnittstellen für eine. Lassen Sie Ihre Ansicht anhand der Werte entscheiden, wie sie aussehen soll. Spielen Sie mit der Ansicht mit Scheindaten. Wenn Sie am Ende eine Ansicht haben, die Ihnen ein Menü (wie im Beispiel) anzeigt, obwohl Sie es zu diesem Zeitpunkt nicht wollten, dann GUT. Ihre Ansicht funktioniert wie es sollte und reagiert auf der Grundlage der Werte wie es sollte. Fügen Sie Ihrem Trigger einfach ein paar weitere Anforderungen hinzu, um sicherzustellen, dass dies nicht passiert, wenn sich das ViewModel in einem bestimmten übersetzten Zustand befindet, oder weisen Sie das ViewModel an, diesen Zustand zu leeren. Entfernen Sie dies in Ihrem ViewModel NICHT mit interner Logik, auch nicht, als würden Sie von dort aus entscheiden, ob die Ansicht es sehen soll oder nicht. Denken Sie daran, dass Sie nicht davon ausgehen können, dass das ViewModel ein Menü enthält oder nicht. Und schließlich sollte das Modell es Ihnen nur ermöglichen, den Speicherstatus zu ändern und höchstwahrscheinlich zu speichern. Hier erfolgt die Validierung und alles wird stattfinden. Wenn das Modell beispielsweise den Status nicht ändern kann, wird es sich einfach als verschmutzt oder etwas anderes markieren. Wenn das ViewModel dies erkennt, übersetzt es das, was schmutzig ist, und die View erkennt dies und zeigt einige Informationen über einen anderen Trigger an. Alle Daten in der Ansicht können an das ViewModel gebunden werden, sodass alles dynamisch sein kann. Nur das Modell und ViewModel haben keinerlei Vorstellung davon, wie die Ansicht auf die Bindung reagieren wird. Tatsächlich hat das Modell auch keine Ahnung von einem ViewModel. Beim Einrichten von Abhängigkeiten sollten sie so und nur so zeigen View → ViewModel → Model (und eine Randnotiz hier ... und dies wird wahrscheinlich auch diskutiert, aber es ist mir egal .. Übergeben Sie das Modell nicht an die Ansicht, es sei denn, das Modell ist unveränderlich. Andernfalls verpacken Sie es in ein ordnungsgemäßes Ansichtsmodell. In der Ansicht sollte keine Modellperiode angezeigt werden , das ist falsch.)

Hier ist mein letzter Tipp ... Sehen Sie sich eine gut gestaltete, aber sehr einfache MVC-Anwendung an und machen Sie dasselbe für eine MVVM-Anwendung. Einer hat mehr Kontrolle mit einer auf Null begrenzten Flexibilität, während der andere keine Kontrolle und unbegrenzte Flexibilität hat.

Eine kontrollierte Umgebung eignet sich für die Verwaltung der gesamten Anwendung von einer Reihe von Controllern oder (einer einzigen Quelle) aus, während eine reaktive Umgebung in separate Repositorys aufgeteilt werden kann, ohne dass Sie eine Vorstellung davon haben, was der Rest der Anwendung tut. Mikromanagement versus freies Management.

Wenn ich Sie nicht genug verwirrt habe, setzen Sie sich mit mir in Verbindung ... Es macht mir nichts aus, dies mit Abbildungen und Beispielen ausführlich zu besprechen.

Am Ende des Tages sind wir alle Programmierer und mit dieser Anarchie leben wir in uns, wenn wir programmieren ... Also werden Regeln gebrochen, Theorien werden sich ändern, und all dies wird in der Schweinewäsche enden ... Aber wenn wir im Großen arbeiten Projekte und in großen Teams hilft es wirklich, ein Entwurfsmuster zu vereinbaren und durchzusetzen. Eines Tages werden die kleinen zusätzlichen Schritte, die zu Beginn unternommen wurden, später zu sprunghaften Einsparungen.

20

MVVM ist eine Verfeinerung (umstritten) des Musters Presentation Model . Ich sage fraglich, weil der einzige Unterschied darin besteht, wie WPF die Möglichkeit bietet, Daten zu binden und Befehle zu verarbeiten.

18
wekempf

Das Ansichtsmodell ist ein "abstraktes" Modell für Ihre Benutzeroberflächenelemente. Sie muss es Ihnen ermöglichen, die Befehle und Aktionen in Ihrer Ansicht nicht visuell auszuführen (z. B. um sie zu testen).

Wenn Sie mit MVC gearbeitet haben, hat es sich möglicherweise als hilfreich erwiesen, Modellobjekte zu erstellen, die den Status Ihrer Ansicht widerspiegeln, z. B. um einige Bearbeitungsdialogfelder usw. anzuzeigen und auszublenden. In diesem Fall verwenden Sie ein Ansichtsmodell.

Das MVVM-Muster ist einfach die Verallgemeinerung dieser Praxis auf alle Elemente der Benutzeroberfläche.

Und es handelt sich nicht um ein Microsoft-Muster, sondern darum, dass WPF/Silverlight-Datenbindungen besonders gut für die Arbeit mit diesem Muster geeignet sind. Aber nichts hindert Sie daran, es zum Beispiel mit Java Server-Faces zu verwenden.

14
DaniCE

Injizieren stark typisierter ViewModels in die Ansicht mithilfe von MVC

  1. Der Controller ist dafür verantwortlich, das ViewModel neu zu erstellen und in die Ansicht einzufügen. (für Anfragen erhalten)
  2. Das ViewModel ist der Container für DataContext und den Ansichtsstatus, z. B. das zuletzt ausgewählte Element usw.
  3. Das Modell enthält DB-Entitäten und ist dem DB-Schema, das die Abfragen und die Filterung durchführt, sehr ähnlich. (Ich mag EF und LINQ dafür)
  4. Das Modell sollte auch Repositorys und/oder die Projektion von Ergebnissen in starke Typen berücksichtigen (EF hat eine großartige Methode ... EF.Database.Select (querystring, parms) für den direkten ADO Zugriff, um Abfragen einzufügen und wieder stark zu werden Typen. Dies adressiert das EF ist langsames Argument. EF ist NICHT LANGSAM!
  5. Das ViewModel ruft die Daten ab und führt die Geschäftsregeln und die Validierung durch
  6. Der Controller on post back ruft die ViewModel Post-Methode auf und wartet auf die Ergebnisse.
  7. Der Controller fügt das neu aktualisierte Ansichtsmodell in die Ansicht ein. Die Ansicht verwendet nur starke Typbindung.
  8. Die Ansicht rendert lediglich die Daten und sendet Ereignisse an die Steuerung zurück. (siehe Beispiele unten)
  9. MVC fängt die eingehende Anforderung ab und leitet sie mit starker Datentyp an den richtigen Controller weiter

In diesem Modell gibt es keinen Kontakt mehr auf HTTP-Ebene mit den Anforderungs- oder Antwortobjekten, da die MVC-Maschine von MSFT dies vor uns verbirgt.

In der Klarstellung von Punkt 6 oben (auf Anfrage) ...

Angenommen, ein ViewModel sieht folgendermaßen aus:

public class myViewModel{
     public string SelectedValue {get;set;}
public void Post(){
    //due to MVC model binding the SelectedValue string above will be set by MVC model binding on post back.
    //this allows you to do something with it.
    DoSomeThingWith(SelectedValue);
    SelectedValue = "Thanks for update!";
 }
}

Die Controller-Methode des Posts sieht folgendermaßen aus (siehe unten). Beachten Sie, dass die Instanz von mvm automatisch durch die MVC-Bindungsmechanismen instanziiert wird. Infolgedessen müssen Sie sich niemals auf die Ebene der Abfragezeichenfolge begeben! Dies ist MVC, das das ViewModel basierend auf den Abfragezeichenfolgen für Sie instanziiert!

[HTTPPOST]   
public ActionResult MyPostBackMethod (myViewModel mvm){
         if (ModelState.IsValid)
        {
               // Immediately call the only method needed in VM...
               mvm.Post()
        }
      return View(mvm);
}

Beachten Sie, dass für diese oben beschriebene Aktionsmethode ein Null-CTOR definiert sein muss, der nicht im Post zurückgegebene Elemente initialisiert, damit sie wie beabsichtigt funktionieren. Das Post-Back muss auch Name/Wert-Paare für die Dinge zurückschicken, die sich geändert haben. Wenn Name/Wert-Paare fehlen, macht die MVC-Bindungs-Engine das Richtige, was einfach nichts ist! In diesem Fall könnten Sie feststellen, dass Sie sagen: "Ich verliere Daten auf Rückseiten" ...

Der Vorteil dieses Musters ist, dass das ViewModel alle "Unordnung" -Aufgaben erledigt, die mit der Model/Buisness-Logik verknüpft sind. Der Controller ist lediglich eine Art Router. Es ist SOC in Aktion.

9
John Peters

Soweit ich weiß, wird die MVVM der MV von MVC zugeordnet - was bedeutet, dass in einem herkömmlichen MVC-Muster die V nicht direkt mit der M kommuniziert. In der zweiten Version von MVC besteht eine direkte Verbindung zwischen M und V. MVVM Anscheinend werden alle Aufgaben im Zusammenhang mit der M- und V-Kommunikation übernommen und von der C-Kommunikation abgekoppelt. Tatsächlich gibt es immer noch den umfangreicheren Anwendungsworkflow (oder die Implementierung der Verwendungsszenarien), die in MVVM nicht vollständig berücksichtigt werden. Dies ist die Rolle des Controllers. Durch das Entfernen dieser untergeordneten Aspekte von den Controllern werden diese sauberer und es wird einfacher, das Verwendungsszenario und die Geschäftslogik der Anwendung zu ändern, wodurch die Wiederverwendbarkeit der Controller verbessert wird.

9
se_thoughts

Die anderen Antworten sind für jemanden, der sich mit Architekturmustern nicht so gut auskennt, möglicherweise nicht leicht zu verstehen. Jemand, der neu in der App-Architektur ist, möchte vielleicht wissen, wie sich die Auswahl auf seine App in der Praxis auswirkt und worum es in den Communities geht.

Um etwas Licht in das oben Genannte zu bringen, habe ich dieses Drehbuch mit MVVM, MVP und MVC geschrieben. Die Geschichte beginnt damit, dass ein Benutzer in einer Filmsuch-App auf die Schaltfläche "SUCHEN" klickt.

Benutzer: Klicken Sie auf ...

Anzeigen: Wer ist das? [ MVVM | MVP | MVC ]

Benutzer: Ich habe gerade auf den Suchknopf geklickt ...

View: Ok, warte eine Sekunde…. [ MVVM | MVP | MVC ]

(View Aufruf des ViewModel | Presenter | Controller…) [ MVVM | MVP | MVC ]

View: Hey ViewModel | Presenter | Controller, ein User hat gerade auf den Suchbutton geklickt, was soll ich machen? [ MVVM | MVP | MVC ]

ViewModel | Presenter | Controller: Hey View, gibt es einen Suchbegriff auf dieser Seite? [ MVVM | MVP | MVC ]

Ansehen: Ja, hier ist es… “Klavier” [ MVVM | MVP | MVC ]

—— Dies ist der wichtigste Unterschied zwischen MVVM UND MVP | MVC ———

Presenter: Danke View,… in der Zwischenzeit suche ich den Suchbegriff auf Model, bitte zeige ihm/ihr einen Fortschrittsbalken [MVP | MVC]

(Presenter | Controller ruft Model… auf) [MVP | MVC]

ViewController: Danke, ich werde den Suchbegriff auf Model nachschlagen, Sie aber nicht direkt aktualisieren. Stattdessen löse ich Ereignisse für searchResultsListObservable aus, wenn ein Ergebnis vorliegt. Also solltest du das besser beobachten. [MVVM]

(Während Sie einen Trigger in searchResultsListObservable beobachten, ist View der Ansicht, dass er dem Benutzer einen Fortschrittsbalken anzeigen sollte, da ViewModel nicht damit sprechen würde.)

———————————————————————————

ViewModel | Presenter | Controller: Hey Model, hast du eine Übereinstimmung für diesen Suchbegriff ?: “piano ”[MVVM | MVP | MVC]

Model: Hey ViewModel | Presenter | Controller, lass mich überprüfen… [MVVM | MVP | MVC]

(Model stellt eine Anfrage an die Filmdatenbank ...) [MVVM | MVP | MVC]

( Nach einer Weile … )

———— Dies ist der abweichende Punkt zwischen MVVM, MVP und MVC ————–

Model: Ich habe eine Liste für dich gefunden, ViewModel | Presenter, hier in JSON “[{“ name ”:” Piano Teacher ” , ”Jahr”: 2001}, {“Name”: ”Klavier”, ”Jahr”: 1993}] ”[MVVM | MVP]

Model: Es ist ein Ergebnis verfügbar, Controller. Ich habe in meiner Instanz eine Feldvariable angelegt und diese mit dem Ergebnis gefüllt. Der Name lautet "searchResultsList". [MVC]

(Presenter | Controller danke Model und kehrt zurück zum View) [MVP | MVC]

Presenter: Danke fürs Warten View, ich habe eine Liste passender Ergebnisse für Sie gefunden und sie in einem ansehnlichen Format angeordnet: ["Piano Teacher 2001", "Piano 1993"] . Verstecke jetzt auch den Fortschrittsbalken [MVP]

Controller: Danke fürs Warten View, ich habe Model nach Ihrer Suchanfrage gefragt. Es heißt, es habe eine Liste passender Ergebnisse gefunden und diese in einer Variablen namens "searchResultsList" in seiner Instanz gespeichert. Sie können es von dort bekommen. Verstecke jetzt auch den Fortschrittsbalken [MVC]

ViewModel: Jeder Beobachter bei searchResultsListObservable wird benachrichtigt, dass es diese neue Liste im präsentierbaren Format gibt: ["Piano Teacher 2001", "Piano 1993"]. [MVVM]

View: Vielen Dank Presenter [MVP]

View: Danke "Controller" [MVC] (Nun das View stellt sich die Frage: Wie soll ich dem Benutzer die Ergebnisse des Model präsentieren? Sollte das Produktionsjahr des Films an erster oder letzter Stelle stehen?)

View: Oh, es gibt einen neuen Trigger in searchResultsListObservable…, gut, es gibt eine präsentierbare Liste, jetzt muss ich sie nur noch in einer Liste anzeigen. Ich sollte jetzt, da ich das Ergebnis habe, auch den Fortschrittsbalken ausblenden. [MVVM]

Falls Sie interessiert sind, habe ich eine Reihe von Artikeln geschrieben hier , die MVVM, MVP und MVC durch Implementierung einer Filmsuch-App Android vergleichen.

9
Ali Nem

MVVM fügt das Ansichtsmodell in den Mix ein. Dies ist wichtig, da Sie einen Großteil des Bindungsansatzes von WPF verwenden können, ohne all diese UI-spezifischen Elemente in Ihr reguläres Modell aufzunehmen.

Ich kann mich irren, bin mir aber nicht sicher, ob MVVM den Controller wirklich in die Mischung zwingt. Ich finde, dass das Konzept mehr im Einklang steht mit: http://martinfowler.com/eaaDev/PresentationModel.html . Ich denke, dass die Leute sich dafür entscheiden, es mit MVC zu kombinieren, nicht dass es in das Muster eingebaut ist.

9
eglasius

Es überrascht mich, dass dies eine hochgelobte Antwort ist, ohne das Origin von MVVM zu erwähnen. MVVM ist ein in der Microsoft-Community verbreiteter Begriff und stammt ​​von Martin Fowlers Präsentationsmodell . Um das Motiv des Musters und die Unterschiede zu anderen zu verstehen, ist der Originalartikel über das Muster das erste, was zu lesen ist.

9
Cheng

Nun, im Allgemeinen wird MVC in der Webentwicklung verwendet und MVVM ist in der WPF/Silverlight-Entwicklung am beliebtesten. Manchmal besteht die Webarchitektur jedoch aus einer Mischung aus MVC und MVVM.

Zum Beispiel: Sie könnten knockout.js verwenden und in diesem Fall haben Sie MVVM auf Ihrer Clientseite. Auch die Serverseite Ihrer MVC kann sich ändern. In den komplexen Apps verwendet niemand das reine Modell. Es könnte sinnvoll sein, ein ViewModel als "Modell" von MVC zu verwenden, und Ihr reales Modell wird im Grunde ein Teil dieser VM sein. Dies gibt Ihnen eine zusätzliche Abstraktionsschicht.

6

Der Controller wird in MVVM nicht durch ein ViewModel ersetzt, da das ViewModel eine völlig andere Funktionalität aufweist als ein Controller. Sie benötigen weiterhin einen Controller, da ViewModel und View ohne einen Controller nicht viel bewirken. In MVVM gibt es auch einen Controller, dessen Name nur irreführend ist.

MVVMC ist meiner bescheidenen Meinung nach der richtige Name.

Wie Sie sehen, ist das ViewModel nur eine Erweiterung des MVC-Musters. Es verschiebt die Konvertierungslogik (zum Beispiel Objekt in einen String konvertieren) vom Controller zum ViewModel.

4
Ini

MVVMC oder vielleicht MVC + scheint ein praktikabler Ansatz für Unternehmen und eine schnelle Anwendungsentwicklung zu sein. Während es sinnvoll ist, die Benutzeroberfläche von der Geschäfts- und Interaktionslogik zu trennen, eignen sich das "reine" MVVM-Muster und die meisten verfügbaren Beispiele am besten für einzelne Ansichten.

Sie sind sich nicht sicher, was Ihre Entwürfe angeht, aber die meisten meiner Anwendungen enthalten Seiten und mehrere (wiederverwendbare) Ansichten. Daher müssen die ViewModels bis zu einem gewissen Grad interagieren. Die Verwendung der Seite als Controller würde den Zweck der MVVM insgesamt zunichte machen. Wenn Sie also keinen "VM-C" -Ansatz für die zugrunde liegende Logik verwenden, kann dies zu ... naja ... herausfordernden Konstrukten führen, wenn die Anwendung ausgereift ist. Selbst in VB-6 haben die meisten von uns wahrscheinlich aufgehört, Geschäftslogik in das Button-Ereignis zu codieren, und haben begonnen, Befehle an einen Controller weiterzuleiten, oder? Ich habe mir kürzlich viele aufkommende Framworks zu diesem Thema angesehen. Mein klarer Favorit ist der Magellan-Ansatz (bei Codeplex). Viel Spaß beim Codieren!

http://en.wikipedia.org/wiki/Model_View_ViewModel#References

4
der Martin

Aus praktischer Sicht ist MVC (Model-View-Controller) ein Muster. Wenn MVC jedoch als ASP.net-MVC verwendet wird, ist es in Kombination mit Entity Framework (EF) und den "Power Tools" ein sehr leistungsfähiger, teilweise automatisierter Ansatz, um Datenbanken, Tabellen und Spalten entweder vollständig auf eine Webseite zu bringen CRUD-Operationen oder nur R-Operationen (Abrufen oder Lesen). Zumindest als ich MVVM verwendete, interagierten die Ansichtsmodelle mit Modellen, die von Geschäftsobjekten abhingen, die wiederum "handgemacht" waren, und nach einer Menge Mühe hatte man das Glück, Modelle zu erhalten, die so gut waren, wie EF es verspricht -der-box ". Vom Standpunkt der praktischen Programmierung aus scheint MVC eine gute Wahl zu sein, da es eine Menge nützlicher Funktionen im Auslieferungszustand bietet, aber es besteht immer noch die Möglichkeit, dass Schnickschnack hinzugefügt wird.

2
JosephDoggie

Ergänzend zu vielen der gegebenen Antworten wollte ich eine zusätzliche Perspektive aus der modernen clientseitigen Web- oder Rich Web Application Sicht hinzufügen.

In der Tat werden heutzutage einfache Websites und größere Webanwendungen häufig mit vielen gängigen Bibliotheken wie Bootstrap erstellt. Knockout wurde von Steve Sanderson erstellt und unterstützt das MVVM-Muster, das eines der wichtigsten Verhaltensweisen des Musters imitiert: Datenbindung über das Ansichtsmodell. Mit ein wenig JavaScript können Daten und Logik implementiert werden, die dann mit einfachen data-bind HTML-Attributen zu Seitenelementen hinzugefügt werden können, ähnlich wie bei Verwendung vieler Funktionen von Bootstrap . Alleine diese beiden Bibliotheken bieten interaktive Inhalte. In Kombination mit dem Routing kann dieser Ansatz zu einem einfachen, aber leistungsstarken Ansatz für die Erstellung der Einzelseitenanwendung führen.

Ebenso folgt ein modernes clientseitiges Framework wie Angular dem MVC-Muster, fügt jedoch auch einen Service hinzu. Interessanterweise wird es als Model-View-Whatever (MVW) angepriesen. (Siehe dieser Beitrag zum Stack Overflow .)

Mit dem Aufkommen von Progressiven Web-Frameworks wie Angular 2 ändert sich außerdem die Terminologie und möglicherweise ein neues Architekturmuster, aus dem Komponenten bestehen eine Ansicht oder Vorlage und die Interaktion mit einem Service - alles kann in einem Modul enthalten sein; und eine Reihe von Modulen bildet die Anwendung.

2

Früher dachte ich, dass MVC und MVVM gleich sind. Nun kann ich aufgrund der Existenz von Flux den Unterschied feststellen:

In MVC haben Sie für jede Ansicht in Ihrer App ein Modell und einen Controller. Ich würde es also Ansicht, Modell anzeigen, Controller anzeigen nennen. Das Muster sagt Ihnen nicht, wie eine Ansicht mit einer anderen kommunizieren kann. Daher gibt es in unterschiedlichen Frameworks unterschiedliche Implementierungen dafür. Beispielsweise gibt es Implementierungen, in denen Controller miteinander kommunizieren, während in anderen Implementierungen eine andere Komponente zwischen ihnen vermittelt. Es gibt sogar Implementierungen, bei denen die Ansichtsmodelle miteinander kommunizieren, was einen Bruch des MVC-Musters darstellt, da auf das Ansichtsmodell nur vom Ansichts-Controller zugegriffen werden sollte.

In MVVM haben Sie auch ein Ansichtsmodell für jede Komponente. Das Muster gibt nicht an, wie die Ansicht das Ansichtsmodell beeinflussen soll, daher enthalten die meisten Frameworks die Funktionalität des Controllers im Ansichtsmodell. MVVM weist Sie jedoch darauf hin, dass die Daten Ihres Ansichtsmodells aus dem Modell stammen sollten. Hierbei handelt es sich um das gesamte Modell, das für eine bestimmte Ansicht weder bekannt noch benutzerdefiniert ist.

Um den Unterschied zu demonstrieren, nehmen wir das Flussmuster. Das Flussmuster gibt an, wie verschiedene Ansichten in der App kommunizieren sollen. Jede Ansicht lauscht einem Geschäft und löst mit dem Dispatcher Aktionen aus. Der Dispatcher informiert seinerseits alle Geschäfte über die gerade durchgeführte Aktion, und die Geschäfte aktualisieren sich. Ein Geschäft in Flux entspricht dem (allgemeinen) Modell in MVVM. Es ist nicht an eine bestimmte Ansicht gebunden. Wenn also Benutzer React und Flux verwenden, implementiert jede React Komponente das MVVM-Muster. Wenn eine Aktion ausgeführt wird, ruft das Ansichtsmodell den Dispatcher auf und wird schließlich entsprechend den Änderungen im Geschäft aktualisiert, bei dem es sich um das Modell handelt. Sie können nicht sagen, dass jede Komponente MVC implementiert, da in MVC nur der Controller das Ansichtsmodell aktualisieren kann. MVVM kann also mit Flux zusammenarbeiten (MVVM übernimmt die Kommunikation zwischen der Ansicht und dem Ansichtsmodell, und Flux übernimmt die Kommunikation zwischen verschiedenen Ansichten), wohingegen MVC nicht mit Flux zusammenarbeiten kann, ohne ein Schlüsselprinzip zu brechen.

2
Alon

mvc ist serverseitig und mvvm ist clientseitig (Browser) in der Webentwicklung.

die meiste Zeit wird Javascript für MVVM im Browser verwendet. es gibt viele serverseitige technologien für mvc.

1
Maulik Gangani

Kurz gesagt: In MVC Controler ist die Ansicht (Steuerelemente) bekannt, während in MVVM ViewModel nicht weiß, wer sie verwendet. ViewModel stellt seine beobachtbaren Eigenschaften und Aktionen allen zur Verfügung, die daran interessiert sein könnten. Diese Tatsache erleichtert das Testen, da in ViewModel kein Verweis auf die Benutzeroberfläche vorhanden ist.

1
daneejela

Heutzutage ist die MVC verpönt und nicht zu Gunsten altruistischer Entwickler.

Viper, React, MVVM, die sind gut, MVC ist schlecht und beschissen ...

Wahrheit oder Mythos?

Nun, MVC ist in der Tat alt und hat mit Sicherheit seine Fehler, am häufigsten die gefürchteten "massiven View Controller".

Aber obwohl die oben genannten neuen Architekturen einige Lösungen für MVC-spezifische Probleme auf den Tisch bringen, weisen sie auch einige Mängel auf, ja, „Niemand ist perfekt“.

MVC ist großartig, Programmierer sind einfach zu nachlässig.

1
Helen Wood