Gibt es einen Unterschied zwischen dem Standardmuster "Model View Controller" und dem Modell / View / ViewModel-Muster von Microsoft?
model-view-controller
mvvm
design-patterns
Björn Reppen
quelle
quelle
Antworten:
MVC / MVVM ist keine Entweder-Oder- Wahl.
Die beiden Muster treten sowohl in der ASP.Net- als auch in der Silverlight / WPF-Entwicklung auf unterschiedliche Weise auf.
Bei ASP.Net wird MVVM zum bidirektionalen Binden von Daten in Ansichten verwendet. Dies ist normalerweise eine clientseitige Implementierung (z. B. mit Knockout.js). MVC hingegen ist eine Möglichkeit, Bedenken auf der Serverseite zu trennen .
Für Silverlight und WPF wird das MVVM Muster umfassenderen und erscheint als Ersatz für MVC (oder andere Muster der Organisation von Software in separate Aufgaben) zu handeln. Eine Annahme, die häufig dieses Musters herauskam, war , dass die
ViewModel
einfach ersetzt den Controller inMVC
(als ob Sie gerade ersetzen könntenVM
fürC
in dem Akronym und alles würde vergeben werden) ...Das ViewModel ersetzt nicht unbedingt die Notwendigkeit separater Controller.
Das Problem ist: Um unabhängig zu testen * und insbesondere bei Bedarf wiederverwendbar zu sein, hat ein Ansichtsmodell keine Ahnung, in welcher Ansicht es angezeigt wird, aber was noch wichtiger ist, keine Ahnung, woher seine Daten stammen .
* Hinweis: In der Praxis entfernen Controller den größten Teil der Logik aus dem ViewModel, für die Unit-Tests erforderlich sind. Die VM wird dann zu einem dummen Container, der nur wenig oder gar keine Tests erfordert. Dies ist eine gute Sache, da die VM nur eine Brücke zwischen dem Designer und dem Codierer darstellt und daher einfach gehalten werden sollte.
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, ist der Hauptvorteil des ViewModel-Musters das Entfernen von Code aus XAML-Code-Behind , um die XAML-Bearbeitung zu einer unabhängigeren Aufgabe zu machen . Wir erstellen weiterhin nach Bedarf Controller, um die Gesamtlogik unserer Anwendungen zu steuern (kein Wortspiel beabsichtigt).
Die grundlegenden MVCVM-Richtlinien, denen wir folgen, sind:
Wir haben auch festgestellt, dass das Sculpture-Code-Gen-Framework MVVM und ein Prisma-ähnliches Muster implementiert UND auch Controller in großem Umfang verwendet, um die gesamte Anwendungsfalllogik zu trennen.
Gehen Sie nicht davon aus, dass Controller durch View-Modelle überholt sind.
Ich habe einen Blog zu diesem Thema gestartet, den ich hinzufügen werde, sobald ich kann . 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 wenig Statusdaten enthalten (dh geringen Speicheraufwand). Dies führt zu weniger speicherintensiven Apps als 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 gelegentlich zwischengespeicherte VMs beibehalten müssen, um die Reaktionsfähigkeit zu gewährleisten.
Hinweis: Dieser Beitrag wurde mehrfach bearbeitet und war nicht speziell auf die gestellte Frage ausgerichtet. Daher habe ich den ersten Teil aktualisiert, um dies jetzt ebenfalls zu behandeln. Ein Großteil der Diskussion in den Kommentaren unten bezieht sich nur auf ASP.Net und nicht auf das Gesamtbild. Dieser Beitrag sollte die breitere Verwendung von MVVM in Silverlight, WPF und ASP.Net behandeln und versuchen, Benutzer davon abzuhalten, Controller durch ViewModels zu ersetzen.
quelle
Ich denke, der einfachste Weg zu verstehen, was diese Akronyme bedeuten sollen, besteht darin, sie für einen Moment zu vergessen. Denken Sie stattdessen an die Software, mit der sie erstellt wurden. Es läuft wirklich nur auf den Unterschied zwischen dem frühen Web und dem Desktop hinaus.
Als ihre Komplexität Mitte der 2000er Jahre zunahm, wurde das MVC-Software-Designmuster, das erstmals in den 1970er Jahren beschrieben wurde, auf Webanwendungen angewendet. Denken Sie dazwischen an Datenbank, HTML-Seiten und Code. Lassen Sie uns dies nur ein wenig verfeinern, um zu MVC zu gelangen: Nehmen wir für »Datenbank« Datenbank plus Schnittstellencode an. Nehmen wir für »HTML-Seiten« HTML-Vorlagen plus Vorlagenverarbeitungscode an. Nehmen wir für »Code dazwischen« an, dass Benutzer, die Codeklicks auf Aktionen zuordnen, möglicherweise Auswirkungen auf die Datenbank haben und definitiv eine andere Ansicht anzeigen. Das war es zumindest für den Zweck dieses Vergleichs.
Lassen Sie uns ein Merkmal dieses Web-Materials beibehalten, nicht wie es heute ist, sondern wie es vor zehn Jahren existierte, als JavaScript ein bescheidener, verabscheuungswürdiger Ärger war, den echte Programmierer gut vermieden haben: Die HTML-Seite ist im Wesentlichen dumm und passiv . Der Browser ist ein Thin Client oder, wenn Sie so wollen, ein schlechter Client. Der Browser enthält keine Informationen. Regel zum erneuten Laden ganzer Seiten. Die »Ansicht« wird jedes Mal neu generiert.
Denken wir daran, dass dieser Web-Weg, obwohl er der letzte Schrei war, im Vergleich zum Desktop schrecklich rückständig war. Desktop-Apps sind Fat Clients oder Rich Clients, wenn Sie so wollen. (Sogar ein Programm wie Microsoft Word kann als eine Art Client betrachtet werden, als Client für Dokumente.) Sie sind Clients voller Intelligenz und Wissen über ihre Daten. Sie sind staatsmännisch. Sie zwischenspeichern Daten, die sie im Speicher verarbeiten. Kein Mist wie ein erneutes Laden der ganzen Seite.
Und auf diese reichhaltige Desktop-Art stammt wahrscheinlich das zweite Akronym, MVVM. Lassen Sie sich nicht von den Buchstaben täuschen, denn das Auslassen der C. Controller sind immer noch da. Sie müssen sein. Nichts wird entfernt. Wir fügen nur eines hinzu: Statefulness, auf dem Client zwischengespeicherte Daten (und zusammen mit dieser Intelligenz, um mit diesen Daten umzugehen). Diese Daten, im Wesentlichen ein Cache auf dem Client, heißen jetzt »ViewModel«. Dies ermöglicht eine reichhaltige Interaktivität. Und das ist es.
Wir können sehen, dass mit Flash, Silverlight und vor allem JavaScript das Web MVVM unterstützt hat. Browser können nicht mehr als Thin Clients bezeichnet werden. Schauen Sie sich ihre Programmierbarkeit an. Schauen Sie sich ihren Speicherverbrauch an. Sehen Sie sich die gesamte Javascript-Interaktivität auf modernen Webseiten an.
Persönlich finde ich diese Theorie und das Akronymgeschäft leichter zu verstehen, wenn ich mir anschaue, worauf es sich in der konkreten Realität bezieht. Abstrakte Konzepte sind nützlich, insbesondere wenn sie in konkreten Fragen demonstriert werden, damit sich das Verständnis schließt.
quelle
MVVM Model-View ViewModel ähnelt MVC, Model-View Controller
Der Controller wird durch ein ViewModel ersetzt . Das ViewModel befindet sich unter der UI-Ebene. Das ViewModel macht die Daten und Befehlsobjekte verfügbar, die die Ansicht benötigt. Sie können sich dies als ein Containerobjekt vorstellen, von dem die Ansicht ihre Daten und Aktionen abruft. Das ViewModel bezieht seine Daten aus dem Modell.
Russel East führt einen Blog durch, in dem ausführlicher diskutiert wird, warum sich MVVM von MVC unterscheidet
quelle
If you put ten software architects into a room and have them discuss what the Model-View-Controller pattern is, you will end up with twelve different opinions. …
Zum einen ist MVVM eine Weiterentwicklung des MVC-Musters, das XAML verwendet, um die Anzeige zu handhaben. Dieser Artikel beschreibt einige der Facetten der beiden.
quelle
Microsoft hat hier eine Erläuterung des MVVM-Musters in der Windows-Umgebung bereitgestellt .
Hier ist ein entscheidender Abschnitt:
quelle
Ich dachte, einer der Hauptunterschiede war, dass in MVC Ihr V Ihr M direkt liest und über das C geht, um die Daten zu manipulieren, während in MVVM Ihre VM als M-Proxy fungiert und Ihnen die verfügbaren Funktionen zur Verfügung stellt V. V.
Wenn ich nicht voll mit Müll bin, bin ich überrascht, dass niemand einen Hybrid erstellt hat, bei dem Ihre VM lediglich ein M-Proxy ist und C alle Funktionen bietet.
quelle
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 Webwelt lässt sich MVC leicht in Ansichtserstellungslogik und Ansichtsdynamiklogik unterteilen. Die Erstellung lebt auf dem Server und die Dynamik lebt 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 es 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 wird der Zyklus fortgesetzt und es gibt viele andere Übersetzungen dieser Behandlung, wenn mit Sockets oder AJAX usw. gearbeitet wird, aber insgesamt ist die Architektur identisch.)
MVVM ist eine reaktive Umgebung, dh Sie schreiben normalerweise Code (z. B. Trigger), der basierend auf einem bestimmten Ereignis aktiviert wird. In XAML, wo MVVM erfolgreich ist, ist dies alles problemlos mit dem integrierten 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, bei dem die Eigenschaft geändert wurde), und die Ansicht reagiert darauf basierend auf den von Ihnen erstellten Triggern. Dies kann technisch werden, aber unter dem Strich ist die Ansicht zustandslos und ohne Logik. Es ändert einfach den Status basierend auf Werten. Darüber hinaus sind ViewModels zustandslos mit sehr wenig Logik, und Modelle sind der Status mit im Wesentlichen Null-Logik, da sie nur den Status beibehalten sollten. Ich beschreibe dies als Anwendungsstatus (Modell), Statusübersetzer (ViewModel) und dann als visuellen Status / Interaktion (Ansicht).
In einer MVC-Desktop- oder clientseitigen Anwendung sollten Sie über ein Modell verfügen, und das Modell sollte 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, da der Controller die Modelle verwaltet und die Modelle an eine ausgewählte Ansicht übergibt. Die Ansicht wird dann mit Daten gefüllt, die auf dem Modell basieren, und verfügt über eine eigene Logik (normalerweise ein anderer MVC-Satz, wie er beispielsweise mit AngularJS erstellt wurde). Die Leute werden 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. Platzieren Sie die Logik und Steuerung bei Verwendung von MVC IMMER an einem Ort. Schreiben Sie die View-Logik NICHT in den Code hinter der View (oder in die View via JS for Web), um Controller- oder Modelldaten aufzunehmen. Lassen Sie den Controller die Ansicht ändern. Die EINZIGE Logik, die in einer Ansicht leben sollte, ist alles, was zum Erstellen und Ausführen über die von ihr verwendete Schnittstelle erforderlich ist. Ein Beispiel hierfür ist die Übermittlung eines Benutzernamens und eines Passworts. Unabhängig davon, ob es sich um einen Desktop oder eine Webseite (auf dem Client) handelt, sollte der Controller den Übermittlungsprozess immer dann ausführen, wenn die Ansicht die Übermittlungsaktion auslöst. Bei korrekter Ausführung können Sie sich jederzeit problemlos in einem MVC-Web oder einer lokalen App zurechtfinden. Unabhängig davon, ob es sich um einen Desktop oder eine Webseite (auf dem Client) handelt, sollte der Controller den Übermittlungsprozess immer dann ausführen, wenn die Ansicht die Übermittlungsaktion auslöst. Bei korrekter Ausführung können Sie sich jederzeit problemlos in einem MVC-Web oder einer lokalen App zurechtfinden. Unabhängig davon, ob es sich um einen Desktop oder eine Webseite (auf dem Client) handelt, sollte der Controller den Übermittlungsprozess immer dann ausführen, wenn die Ansicht die Übermittlungsaktion auslöst. Bei korrekter 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 Modell den Status ändert, hört und übersetzt das ViewModel diesen Status und das wars !!! Die Ansicht wartet dann auf das ViewModel, um den Status zu ändern, und es wird auch basierend auf der Übersetzung aus dem ViewModel aktualisiert. Einige Leute nennen es reines MVVM, aber es gibt wirklich nur eines, und es ist mir egal, wie Sie es argumentieren, und es ist immer reines MVVM, wo die Ansicht absolut keine Logik enthält.
Hier ein kleines Beispiel: Nehmen wir an, Sie möchten, dass ein Menü auf Knopfdruck eingeblendet wird. In MVC haben Sie eine MenuPressed-Aktion in Ihrer Benutzeroberfläche. Der Controller weiß, wann Sie auf die Schaltfläche Menü klicken und dann die Ansicht anweisen, auf der Grundlage einer anderen Schnittstellenmethode wie SlideMenuIn in das Menü zu wechseln. Eine Rundreise aus welchem Grund? Wenn der Controller entscheidet, dass Sie stattdessen 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 allgemein gehalten sein. Anstatt angewiesen zu werden, es einzuschieben, wird dies basierend auf einem bestimmten Wert durchgeführt. Es hört also auf das ViewModel und wenn das ViewModel sagt, IsMenuActive = true (oder jedoch), findet die Animation dafür statt. Jetzt, Vor diesem Hintergrund möchte ich noch einen Punkt hervorheben, der WIRKLICH KLAR ist, und BITTE achten Sie darauf. IsMenuActive ist wahrscheinlich ein schlechtes MVVM- oder ViewModel-Design. Wenn Sie ein ViewModel entwerfen, sollten Sie niemals davon ausgehen, dass eine Ansicht überhaupt Funktionen enthält, 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 (wahrscheinlich ein Array von inneren ViewModels) zu geben. 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 ein- oder 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 absolut keinen Sinn, wenn Sie nicht bereits ein wenig mit der Architektur der einzelnen vertraut sind und das Lernen sehr verwirrend sein kann, da Sie VIELE SCHLECHTE Informationen im Internet finden.
Also ... Dinge, die Sie beachten sollten, um dies richtig zu machen. Entscheiden Sie im Voraus, wie Sie Ihre Anwendung gestalten möchten, und bleiben Sie dabei.
Wenn Sie MVC ausführen, was großartig ist, stellen Sie sicher, dass Ihr Controller verwaltbar ist und die volle Kontrolle über Ihre Ansicht hat. Wenn Sie eine große Ansicht haben, sollten Sie der Ansicht Steuerelemente hinzufügen, die unterschiedliche Controller haben. Kaskadieren Sie diese Controller NUR NICHT an andere Controller. Sehr frustrierend zu pflegen. Nehmen Sie sich einen Moment Zeit und entwerfen Sie die Dinge separat, so dass sie als separate Komponenten funktionieren. Lassen Sie den Controller das Modell immer anweisen, den Speicher festzuschreiben oder beizubehalten. Das ideale Abhängigkeits-Setup für MVC in ist Ansicht ← Controller → Modell oder mit ASP.NET (nicht anfangen) Modell ← Ansicht ↔ Controller → Modell (wobei Modell von Controller zu Ansicht dasselbe oder ein völlig anderes Modell sein kann)... Natürlich müssen Sie Controller in View an dieser Stelle nur kennen, um zu wissen, wohin Sie ein Modell zurückgeben müssen.
Wenn Sie MVVM machen, segne ich Ihre freundliche Seele, aber nehmen Sie sich die Zeit, es richtig zu machen! Verwenden Sie keine Schnittstellen für eine. Lassen Sie Ihre Ansicht anhand von Werten entscheiden, wie sie aussehen soll. Spielen Sie mit der Ansicht mit Scheindaten. Wenn Sie am Ende eine Ansicht haben, die Ihnen ein Menü zeigt (wie im Beispiel gezeigt), obwohl Sie es zu diesem Zeitpunkt nicht wollten, dann GUT. Ihre Ansicht funktioniert wie es sollte und reagiert basierend auf den Werten wie es sollte. Fügen Sie Ihrem Trigger einfach einige weitere Anforderungen hinzu, um sicherzustellen, dass dies nicht geschieht, wenn sich das ViewModel in einem bestimmten übersetzten Zustand befindet, oder befehlen Sie dem ViewModel, diesen Zustand zu leeren. Entfernen Sie dies in Ihrem ViewModel NICHT mit interner Logik, als ob Sie von dort aus entscheiden würden, 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 schlussendlich, Das Modell sollte es Ihnen nur ermöglichen, den Status zu ändern und höchstwahrscheinlich zu speichern. Hier erfolgt die Validierung und alles wird stattfinden. Wenn das Modell beispielsweise den Status nicht ändern kann, markiert es sich einfach als schmutzig oder so. Wenn das ViewModel dies erkennt, übersetzt es, was schmutzig ist, und die Ansicht erkennt dies und zeigt einige Informationen über einen anderen Trigger an. Alle Daten in der Ansicht können an das ViewModel gebunden werden, sodass nur das Modell dynamisch sein kann. ViewModel hat absolut keine Ahnung, wie die Ansicht auf die Bindung reagiert. Tatsächlich hat das Modell auch keine Ahnung von einem ViewModel. Beim Einrichten von Abhängigkeiten sollten sie so und nur so zeigen Wenn Sie den Status nicht ändern, wird er sich einfach als schmutzig oder so kennzeichnen. Wenn das ViewModel dies erkennt, übersetzt es, was schmutzig ist, und die Ansicht erkennt dies und zeigt einige Informationen über einen anderen Trigger an. Alle Daten in der Ansicht können an das ViewModel gebunden werden, sodass nur das Modell dynamisch sein kann. ViewModel hat absolut keine Ahnung, wie die Ansicht auf die Bindung reagiert. Tatsächlich hat das Modell auch keine Ahnung von einem ViewModel. Beim Einrichten von Abhängigkeiten sollten sie so und nur so zeigen Wenn Sie den Status nicht ändern, wird er sich einfach als schmutzig oder so kennzeichnen. Wenn das ViewModel dies erkennt, übersetzt es, was schmutzig ist, und die Ansicht erkennt dies und zeigt einige Informationen über einen anderen Trigger an. Alle Daten in der Ansicht können an das ViewModel gebunden werden, sodass nur das Modell dynamisch sein kann. ViewModel hat absolut keine Ahnung, wie die Ansicht auf die Bindung reagiert. Tatsächlich hat das Modell auch keine Ahnung von einem ViewModel. Beim Einrichten von Abhängigkeiten sollten sie so und nur so zeigen Alle Daten in der Ansicht können an das ViewModel gebunden werden, sodass nur das Modell dynamisch sein kann. ViewModel hat absolut keine Ahnung, wie die Ansicht auf die Bindung reagiert. Tatsächlich hat das Modell auch keine Ahnung von einem ViewModel. Beim Einrichten von Abhängigkeiten sollten sie so und nur so zeigen Alle Daten in der Ansicht können an das ViewModel gebunden werden, sodass nur das Modell dynamisch sein kann. ViewModel hat absolut keine Ahnung, wie die Ansicht auf die Bindung reagiert. Tatsächlich hat das Modell auch keine Ahnung von einem ViewModel. Beim Einrichten von Abhängigkeiten sollten sie so und nur so zeigenAnsicht → Ansichtsmodell → Modell (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, dieses Modell ist unveränderlich, andernfalls wickeln Sie es mit einem richtiges ViewModel. Die Ansicht sollte keine Modellperiode sehen. Ich gebe einer Ratte einen Riss, welche Demo Sie gesehen haben oder wie Sie es gemacht haben, 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 bei begrenzter Flexibilität, während der andere keine Kontrolle und unbegrenzte Flexibilität hat.
Eine kontrollierte Umgebung eignet sich gut zum Verwalten 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 eine Ahnung davon besteht, was der Rest der Anwendung tut. Mikromanagement vs. freies Management.
Wenn ich Sie nicht genug verwirrt habe, versuchen Sie, mich zu kontaktieren ... Es macht mir nichts aus, dies ausführlich mit Abbildungen und Beispielen 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 zu Schweinewaschung führen ... Aber wenn wir im Großen und Ganzen arbeiten In Projekten und in großen Teams ist es wirklich hilfreich, sich auf ein Entwurfsmuster zu einigen und es durchzusetzen. Eines Tages werden die kleinen zusätzlichen Schritte, die am Anfang unternommen wurden, später zu sprunghaften Einsparungen.
quelle
Einfacher Unterschied: (Inspiriert von Yaakovs Coursera AngularJS-Kurs)
MVC (Model View Controller)
MVVM (Model View View Model)
ViewModel :
quelle
MVVM ist eine Verfeinerung (umstritten) des Präsentationsmodellmusters . Ich sage umstritten, weil der einzige Unterschied darin besteht, wie WPF die Möglichkeit bietet, Daten zu binden und Befehle zu verarbeiten.
quelle
Das Ansichtsmodell ist ein "abstraktes" Modell für Ihre Benutzeroberflächenelemente. Es muss Ihnen ermöglichen, die Befehle und Aktionen in Ihrer Ansicht nicht visuell auszuführen (zum Beispiel um sie zu testen).
Wenn Sie mit MVC gearbeitet haben, haben Sie es wahrscheinlich manchmal als nützlich empfunden, Modellobjekte zu erstellen, die den Status Ihrer Ansicht widerspiegeln, z. B. um einige Bearbeitungsdialoge ein- und auszublenden usw. In diesem Fall verwenden Sie ein Ansichtsmodell.
Das MVVM-Muster ist einfach die Verallgemeinerung dieser Praxis auf alle UI-Elemente.
Und es ist kein Microsoft-Muster. Was beigefügt ist, ist, dass WPF / Silverlight-Datenbindungen besonders gut für die Arbeit mit diesem Muster geeignet sind. Nichts hindert Sie jedoch daran, es beispielsweise mit Java-Servergesichtern zu verwenden.
quelle
Die anderen Antworten sind möglicherweise nicht leicht zu verstehen für jemanden, der mit dem Thema Architekturmuster nicht sehr vertraut ist. Jemand, der neu in der App-Architektur ist, möchte vielleicht wissen, wie sich die Auswahl auf seine App in der Praxis auswirken kann und worum es in den Communities geht.
Ich habe versucht, etwas Licht in das Obige zu bringen, und dieses Drehbuch mit MVVM, MVP und MVC verfasst. Die Geschichte beginnt damit, dass ein Benutzer in einer Filmsuch-App auf die Schaltfläche 'FIND' klickt…:
Benutzer: Klicken Sie auf…
Ansicht : Wer ist das? [ MVVM | MVP | MVC ]
Benutzer: Ich habe gerade auf die Suchschaltfläche geklickt…
Ansicht : Ok, warte eine Sekunde…. [ MVVM | MVP | MVC ]
( Ansicht beim Aufrufen von ViewModel | Presenter | Controller …) [ MVVM | MVP | MVC ]
Ansicht : Hey ViewModel | Moderator | Controller , ein Benutzer hat gerade auf die Suchschaltfläche geklickt. Was soll ich tun? [ MVVM | MVP | MVC ]
ViewModel | Moderator | Controller : Hey View , gibt es einen Suchbegriff auf dieser Seite? [ MVVM | MVP | MVC ]
Ansicht : Ja,… hier ist es… „Klavier“ [ MVVM | MVP | MVC ]
—— Dies ist der wichtigste Unterschied zwischen MVVM UND MVP | MVC ———
Moderator : Danke View ,… während ich den Suchbegriff für das Modell nachschlage, zeigen Sie ihm / ihr bitte einen Fortschrittsbalken [ MVP | MVC ]
( Presenter | Controller ruft das Modell auf …) [ MVP | MVC ]
ViewController : Danke, ich werde den Suchbegriff im Modell nachschlagen , Sie aber nicht direkt aktualisieren. Stattdessen werde ich Ereignisse für searchResultsListObservable auslösen, wenn ein Ergebnis vorliegt. Also solltest du das besser beobachten. [ MVVM ]
(Während Sie einen Trigger in searchResultsListObservable beobachten, ist die Ansicht der Ansicht, dass dem Benutzer ein Fortschrittsbalken angezeigt werden sollte, da ViewModel diesbezüglich nicht mit ihm sprechen würde.)
————————————————————————————————
ViewModel | Moderator | Controller : Hey Model , haben Sie eine Übereinstimmung mit diesem Suchbegriff?: "Piano" [ MVVM | MVP | MVC ]
Modell : Hey ViewModel | Moderator | Controller , lassen Sie mich überprüfen ... [ MVVM | MVP | MVC ]
( Model stellt eine Abfrage an die Filmdatenbank…) [ MVVM | MVP | MVC ]
( Nach einer Weile … )
———— Dies ist der divergierende Punkt zwischen MVVM , MVP und MVC ————–
Modell : Ich habe eine Liste für Sie gefunden, ViewModel | Moderator , hier ist es in JSON "[{" Name ":" Klavierlehrer "," Jahr ": 2001}, {" Name ":" Klavier "," Jahr ": 1993}]" [ MVVM | MVP ]
Modell : Es sind einige Ergebnisse verfügbar, Controller. Ich habe in meiner Instanz eine Feldvariable erstellt und mit dem Ergebnis gefüllt. Der Name lautet "searchResultsList" [ MVC ]
( Presenter | Controller bedankt sich bei Model und kehrt zur Ansicht zurück ) [ MVP | MVC ]
Moderator : Danke, dass Sie auf View gewartet haben haben. Ich habe eine Liste mit übereinstimmenden Ergebnissen für Sie gefunden und sie in einem vorzeigbaren Format angeordnet: ["Piano Teacher 2001", "Piano 1993"]. Bitte verstecken Sie jetzt auch den Fortschrittsbalken [ MVP ]
Controller : Danke, dass Sie auf View gewartet haben haben. Ich habe Model nach Ihrer Suchanfrage gefragt. Es heißt, es habe eine Liste übereinstimmender Ergebnisse gefunden und diese in einer Variablen namens "searchResultsList" in seiner Instanz gespeichert. Sie können es von dort bekommen. Bitte verstecken Sie jetzt auch den Fortschrittsbalken [ MVC ]
ViewModel : Jeder Beobachter auf searchResultsListObservable wird benachrichtigt, dass es diese neue Liste im vorzeigbaren Format gibt: ["Piano Teacher 2001", "Piano 1993"]. [ MVVM ]
Ansicht : Vielen Dank Presenter [ MVP ]
Ansicht : Vielen Dank, " Controller " [ MVC ] (Jetzt fragt sich die Ansicht selbst: Wie soll ich dem Benutzer die Ergebnisse präsentieren, die ich vom Modell erhalte ? Sollte das Produktionsjahr des Films an erster oder letzter Stelle stehen ...?)
Ansicht : Oh, es gibt einen neuen Auslöser in searchResultsListObservable…, gut, es gibt eine präsentierbare Liste, jetzt muss ich sie nur noch in einer Liste anzeigen. Ich sollte jetzt auch den Fortschrittsbalken ausblenden, wenn ich das Ergebnis habe. [ MVVM ]
Falls Sie interessiert sind, habe ich eine Reihe von Artikeln geschrieben hier , verglichen MVVM, MVP und MVC durch einen Film suchen Android App implementieren.
quelle
Injizieren stark typisierter ViewModels mit MVC in die Ansicht
In diesem Modell gibt es keine HTTP-Ebene mehr Kontakt mit den Anforderungs- oder Antwortobjekten, da der MVC-Computer von MSFT ihn vor uns verbirgt.
Zur Verdeutlichung von Punkt 6 oben (auf Anfrage) ...
Nehmen Sie ein ViewModel wie folgt an:
Die Controller-Methode des Beitrags sieht folgendermaßen aus (siehe unten). Beachten Sie, dass die Instanz von mvm automatisch von den MVC-Bindungsmechanismen instanziiert wird. Sie müssen daher nie auf die Abfragezeichenfolgenebene fallen! Dies ist MVC, das das ViewModel basierend auf den Abfragezeichenfolgen für Sie instanziiert!
Beachten Sie, dass für diese oben beschriebene Aktionsmethode ein Null-CTOR definiert sein muss, der Dinge initialisiert, die nicht im Beitrag zurückgegeben werden. Das Zurücksenden muss auch Name / Wert-Paare für die Dinge zurücksenden, 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 sagen: "Ich verliere Daten bei Post-Backs" ...
Der Vorteil dieses Musters ist, dass das ViewModel die gesamte "Unordnung" erledigt, die mit der Modell- / Geschäftslogik verbunden ist. Der Controller ist lediglich eine Art Router. Es ist SOC in Aktion.
quelle
MVVM fügt das Ansichtsmodell dem Mix hinzu. Dies ist wichtig, da Sie so einen Großteil des Bindungsansatzes von WPF verwenden können, ohne all diese UI-spezifischen Teile in Ihr reguläres Modell aufzunehmen.
Ich kann mich irren, aber ich bin nicht sicher, ob MVVM den Controller wirklich in den Mix zwingt. Ich finde das Konzept eher im Einklang mit: http://martinfowler.com/eaaDev/PresentationModel.html . Ich denke, dass die Leute es mit MVC kombinieren, nicht dass es in das Muster eingebaut ist.
quelle
Soweit ich das beurteilen kann, ist die MVVM der MV von MVC zugeordnet - was bedeutet, dass in einem herkömmlichen MVC-Muster das V nicht direkt mit dem M kommuniziert. In der zweiten Version von MVC besteht eine direkte Verbindung zwischen M und V. MVVM scheint alle Aufgaben im Zusammenhang mit der M- und V-Kommunikation zu übernehmen und zu koppeln, um sie von C zu entkoppeln. Tatsächlich gibt es immer noch den Anwendungsworkflow mit größerem Umfang (oder die Implementierung der Verwendungsszenarien), der in MVVM nicht vollständig berücksichtigt wird. Dies ist die Rolle des Controllers. Durch das Entfernen dieser untergeordneten Aspekte von den Controllern werden sie sauberer und erleichtern das Ändern des Anwendungsszenarios und der Geschäftslogik der Anwendung, wodurch Controller wiederverwendbarer werden.
quelle
Es überrascht mich, dass dies eine hoch bewertete Antwort ist, ohne den Ursprung von MVVM zu erwähnen . MVVM ist ein beliebter Begriff in der Microsoft-Community und stammt aus dem Präsentationsmodell von Martin Fowler . Um das Motiv des Musters und die Unterschiede zu anderen zu verstehen, sollte zuerst der Originalartikel über das Muster gelesen werden.
quelle
Nun, im Allgemeinen wird MVC in der Webentwicklung verwendet und MVVM ist in der WPF / Silverlight-Entwicklung am beliebtesten. Manchmal kann die Web-Architektur jedoch eine Mischung aus MVC und MVVM enthalten.
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 kann 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.
quelle
MVVMC oder vielleicht MVC + scheint ein praktikabler Ansatz für Unternehmen und eine schnelle Anwendungsentwicklung zu sein. Während es schön ist, die Benutzeroberfläche von der Geschäfts- und Interaktionslogik zu trennen, funktionieren das "reine" MVVM-Muster und die meisten verfügbaren Beispiele am besten für einzelne Ansichten.
Sie sind sich über Ihre Designs nicht sicher, aber die meisten meiner Anwendungen enthalten jedoch 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 ... 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 damit begonnen, Befehle an einen Controller weiterzuleiten, oder? Ich habe mir kürzlich viele aufkommende Rahmenwerke zu diesem Thema angesehen. Mein Favorit ist eindeutig der Magellan-Ansatz (bei Codeplex). Viel Spaß beim Codieren!
http://en.wikipedia.org/wiki/Model_View_ViewModel#References
quelle
Der Controller wird in MVVM nicht durch ein ViewModel ersetzt, da das ViewModel eine völlig andere Funktionalität als ein Controller hat. Sie benötigen noch einen Controller, da Ihr Modell, ViewModel und View ohne Controller nicht viel bewirken ... In MVVM haben Sie auch einen Controller, der Name MVVM ist nur irreführend.
MVVMC ist meiner bescheidenen Meinung nach der richtige Name.
Wie Sie sehen, ist das ViewModel nur eine Ergänzung zum MVC-Muster. Die Konvertierungslogik (z. B. Objekt in eine Zeichenfolge konvertieren) wird vom Controller in das ViewModel verschoben.
quelle
Ich habe dafür einen Medium-Artikel gemacht.
MVVM
Ansicht ➡ ViewModel ➡ Modell
Wenn Sie einen Controller verwenden, kann dieser auf Views und ViewModels verweisen , obwohl ein Controller nicht immer erforderlich ist, wie in SwiftUI gezeigt .
Unterschiede im Setup
Gemeinsamkeiten
Vorteile von MVVM
Vorteile von MVC
quelle
Aus praktischer Sicht ist MVC (Model-View-Controller) ein Muster. Wenn MVC als ASP.net MVC verwendet wird, ist es in Kombination mit Entity Framework (EF) und den "Elektrowerkzeugen" ein sehr leistungsfähiger, teilweise automatisierter Ansatz, um Datenbanken, Tabellen und Spalten entweder vollständig auf eine Webseite zu bringen Nur CRUD-Operationen oder 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 viel Mühe hatte man das Glück, Modelle so gut zu bekommen, wie EF sie herausgibt -of-the-Box ". Aus praktischer Sicht der Programmierung scheint MVC eine gute Wahl zu sein, da es eine Menge sofort einsatzbereiter Hilfsprogramme bietet, aber es besteht immer noch die Möglichkeit, dass Schnickschnack hinzugefügt wird.
quelle
Ergänzend zu vielen der gegebenen Antworten wollte ich eine zusätzliche Perspektive aus der Sicht des modernen clientseitigen Web - oder der Rich Web Application - 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 entwickelt und bietet Unterstützung für das MVVM-Muster, das eines der wichtigsten Verhaltensweisen des Musters nachahmt: Datenbindung über das Ansichtsmodell. Mit ein wenig JavaScript können Daten und Logik implementiert werden, die dann zu Seitenelementen mit einfachen
data-bind
HTML-Attributen hinzugefügt werden können, ähnlich wie bei vielen Funktionen von Bootstrap . Zusammen bieten diese beiden Bibliotheken interaktive Inhalte. In Kombination mit dem Routing kann dieser Ansatz zu einem einfachen, aber leistungsstarken Ansatz zum Erstellen der Einzelseitenanwendung führen .In ähnlicher Weise folgt ein modernes clientseitiges Framework wie Angular gemäß Konvention dem MVC-Muster, fügt jedoch auch einen Service hinzu. Interessanterweise wird es als Model-View-Whatever (MVW) angepriesen. (Siehe diesen Beitrag zum Stapelüberlauf .)
Mit dem Aufkommen von progressiven Webframeworks wie Angular 2 sehen wir außerdem eine Änderung der Terminologie und möglicherweise ein neues Architekturmuster, bei dem Komponenten aus einer Ansicht oder Vorlage bestehen und mit einem Dienst interagieren - die alle in einem enthalten sein können Modul; und eine Reihe von Modulen bildet die Anwendung.
quelle
Früher dachte ich, dass MVC und MVVM gleich sind. Aufgrund der Existenz von Flux kann ich nun den Unterschied erkennen:
In MVC haben Sie für jede Ansicht in Ihrer App ein Modell und einen Controller. Ich würde es also Ansicht, Ansichtsmodell, Ansichtscontroller 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, bei denen Controller miteinander kommunizieren, während bei anderen Implementierungen eine andere Komponente zwischen ihnen vermittelt. Es gibt sogar Implementierungen, bei denen die Ansichtsmodelle miteinander kommunizieren. Dies ist eine Unterbrechung des MVC-Musters, da nur der Ansichtscontroller auf das Ansichtsmodell zugreifen sollte.
In MVVM haben Sie auch ein Ansichtsmodell für jede Komponente. Das Muster gibt nicht an, wie zum Teufel die Ansicht das Ansichtsmodell beeinflussen soll. Daher enthalten die meisten Frameworks normalerweise nur die Funktionalität des Controllers im Ansichtsmodell. MVVM teilt Ihnen jedoch mit, dass die Daten Ihres Ansichtsmodells aus dem Modell stammen sollten. Dies ist das gesamte Modell, das für eine bestimmte Ansicht nicht bekannt oder 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 hört sich ein Geschäft an und löst mithilfe des Dispatchers Aktionen aus. Der Dispatcher wiederum informiert alle Filialen über die gerade durchgeführte Aktion, und die Filialen aktualisieren sich selbst. Ein Geschäft in Flux entspricht dem (allgemeinen) Modell in MVVM. Es ist nicht an eine bestimmte Ansicht angepasst. Wenn Benutzer React und Flux verwenden, implementiert normalerweise 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, dem Modell, aktualisiert. Sie können nicht sagen, dass jede Komponente MVC implementiert, da in MVC nur der Controller das Ansichtsmodell aktualisieren kann.
quelle
mvc ist serverseitig und mvvm ist clientseitig (Browser) in der Webentwicklung.
Meistens wird Javascript für mvvm im Browser verwendet. Es gibt viele serverseitige Technologien für MVC.
quelle
Kurz gesagt: In MVC ist Controler die Ansicht (Steuerelemente) bekannt, während ViewModel in MVVM nicht weiß, wer sie verwendet. ViewModel stellt seine beobachtbaren Eigenschaften und Aktionen jedem zur Verfügung, der daran interessiert sein könnte, es zu verwenden. Diese Tatsache erleichtert das Testen, da in ViewModel kein Verweis auf die Benutzeroberfläche vorhanden ist.
quelle
Model-View-Controller (normalerweise als MVC bekannt) ) ist ein Software-Entwurfsmuster, das üblicherweise zum Entwickeln von Benutzeroberflächen verwendet wird, die die zugehörige Programmlogik in drei miteinander verbundene Elemente unterteilen. Dies geschieht, um interne Darstellungen von Informationen von der Art und Weise zu trennen, wie Informationen dem Benutzer präsentiert und vom Benutzer akzeptiert werden. Das Befolgen des MVC-Architekturmusters entkoppelt diese Hauptkomponenten und ermöglicht die Wiederverwendung von Code und die parallele Entwicklung.
Dieses Muster wird traditionell für grafische Desktop-Benutzeroberflächen (GUIs) verwendet und ist für das Entwerfen von Webanwendungen beliebt geworden. Beliebte Programmiersprachen wie JavaScript, Python, Ruby, PHP, Java und C # verfügen über MVC-Frameworks, die sofort in der Entwicklung von Webanwendungen verwendet werden.
Modell
Die zentrale Komponente des Musters. Dies ist die dynamische Datenstruktur der Anwendung, unabhängig von der Benutzeroberfläche. Es verwaltet direkt die Daten, die Logik und die Regeln der Anwendung.
Aussicht
Beliebige Darstellung von Informationen wie Diagrammen, Diagrammen oder Tabellen. Es sind mehrere Ansichten derselben Informationen möglich, z. B. ein Balkendiagramm für die Verwaltung und eine tabellarische Ansicht für Buchhalter.
Regler
Akzeptiert Eingaben und konvertiert sie in Befehle für das Modell oder die Ansicht.
Das Modell-Ansicht-Controller-Design unterteilt die Anwendung nicht nur in diese Komponenten, sondern definiert auch die Wechselwirkungen zwischen ihnen.
Das Modell ist für die Verwaltung der Daten der Anwendung verantwortlich. Es empfängt Benutzereingaben von der Steuerung.
Die Ansicht bedeutet eine Darstellung des Modells in einem bestimmten Format.
Die Steuerung reagiert auf Benutzereingaben und führt Interaktionen mit den Datenmodellobjekten durch. Die Steuerung empfängt die Eingabe, validiert sie optional und übergibt sie dann an das Modell.
Model-View-ViewModel (MVVM) ist ein Software-Architekturmuster.
MVVM erleichtert die Trennung der Entwicklung der grafischen Benutzeroberfläche - sei es über eine Auszeichnungssprache oder einen GUI-Code - von der Entwicklung der Geschäftslogik oder der Back-End-Logik (dem Datenmodell). Das Ansichtsmodell von MVVM ist ein Wertekonverter, dh das Ansichtsmodell ist dafür verantwortlich, die Datenobjekte aus dem Modell so verfügbar zu machen (zu konvertieren), dass Objekte einfach verwaltet und dargestellt werden können. In dieser Hinsicht ist das Ansichtsmodell mehr Modell als eine Ansicht und verarbeitet die meisten, wenn nicht die gesamte Anzeigelogik der Ansicht. Das Ansichtsmodell kann ein Mediatormuster implementieren, das den Zugriff auf die Back-End-Logik um den Satz von Anwendungsfällen herum organisiert, die von der Ansicht unterstützt werden.
MVVM ist eine Variation des Entwurfsmusters des Präsentationsmodells von Martin Fowler. MVVM abstrahiert den Status und das Verhalten einer Ansicht auf dieselbe Weise, aber ein Präsentationsmodell abstrahiert eine Ansicht (erstellt ein Ansichtsmodell) auf eine Weise, die nicht von einer bestimmten Benutzeroberflächenplattform abhängig ist.
MVVM wurde von den Microsoft-Architekten Ken Cooper und Ted Peters speziell erfunden, um die ereignisgesteuerte Programmierung von Benutzeroberflächen zu vereinfachen. Das Muster wurde in Windows Presentation Foundation (WPF) (Microsoft .NET-Grafiksystem) und Silverlight (WPFs Internetanwendungsderivat) integriert. John Gossman, einer der WPF- und Silverlight-Architekten von Microsoft, kündigte MVVM 2005 in seinem Blog an.
Model-View-ViewModel wird auch als Model-View-Binder bezeichnet, insbesondere in Implementierungen, an denen die .NET-Plattform nicht beteiligt ist. ZK (ein in Java geschriebenes Webanwendungsframework) und KnockoutJS (eine JavaScript-Bibliothek) verwenden Model-View-Binder.
quelle