MVC ist eine kontrollierte Umgebung und MVVM ist eine reaktive Umgebung.
In einer kontrollierten Umgebung sollten Sie weniger Code und eine gemeinsame Quelle für die Logik haben, die immer innerhalb des Controllers liegen sollte. In der Webwelt wird MVC jedoch leicht in Logik für die Erstellung von Ansichten und dynamische Logik für Ansichten unterteilt. Die Erstellung erfolgt auf dem Server und die Dynamik auf dem Client. Man sieht dies häufig bei ASP.NET MVC in Kombination mit AngularJS, wobei der Server eine Ansicht erstellt, ein Modell übergibt und es an den Client sendet. Der Client interagiert dann mit der Ansicht, wobei AngularJS als lokaler Controller eingesetzt wird. Nach der Übermittlung wird das Model oder ein neues Model an den Server-Controller zurückgegeben und verarbeitet. (Auf diese Weise setzt sich der Zyklus fort, und es gibt viele andere Übersetzungen dieser Handhabung bei der Arbeit mit Sockets oder AJAX usw., aber insgesamt ist die Architektur identisch).
MVVM ist eine reaktive Umgebung, d.h. Sie schreiben typischerweise Code (wie z.B. Trigger), der auf der Grundlage eines Ereignisses aktiviert wird. In XAML, wo MVVM gedeiht, ist dies alles leicht mit dem eingebauten Datenbindungs-Framework getan, ABER wie erwähnt wird dies auf jedem System in jeder Ansicht mit jeder Programmiersprache funktionieren. Es ist nicht MS-spezifisch. Das ViewModel löst ein Ereignis aus (in der Regel ein Ereignis zur Änderung einer Eigenschaft) und die View reagiert darauf, basierend auf den von Ihnen erstellten Auslösern. Das kann technisch werden, aber im Grunde ist die View zustandslos und ohne Logik. Sie ändert einfach ihren Zustand auf der Grundlage von Werten. 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 aufrechterhalten sollen. Ich beschreibe dies als Anwendungszustand (Model), Zustandsübersetzer (ViewModel), und dann den visuellen Zustand / die Interaktion (View).
In einer MVC-Desktop- oder Client-Side-Anwendung sollten Sie ein Modell haben, und das Modell sollte vom Controller verwendet werden. Auf der Grundlage des Modells wird der Controller die Ansicht ändern. Ansichten sind in der Regel über Schnittstellen mit Controllern verbunden, so dass 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 weitergibt. Die View wird dann auf der Grundlage des Modells mit Daten gefüllt und verfügt über eine eigene Logik (in der Regel ein weiterer MVC-Satz, wie er bei AngularJS verwendet wird). Die Leute werden argumentieren und dies mit Anwendungs-MVC verwechseln und versuchen, beides zu tun, wobei die Aufrechterhaltung des Projekts schließlich zu einer Katastrophe wird. Legen Sie bei der Verwendung von MVC IMMER die Logik und die Kontrolle an einer Stelle ab. Schreiben Sie KEINE View-Logik in den Code hinter der View (oder in die View über JS für das Web), um Controller- oder Modelldaten anzupassen. Lassen Sie den Controller die View ändern. Die EINZIGE Logik, die in einer View enthalten sein sollte, ist die, die zum Erstellen und Ausführen über die verwendete Schnittstelle erforderlich ist. Ein Beispiel hierfür ist die Übermittlung eines Benutzernamens und eines Passworts. Ob auf dem Desktop oder auf der Webseite (auf dem Client), der Controller sollte den Übermittlungsprozess immer dann abwickeln, wenn die View die Submit-Aktion auslöst. Wenn dies richtig gemacht wird, können Sie sich immer leicht in einer MVC-Web- oder lokalen Anwendung zurechtfinden.
MVVM ist persönlich mein Favorit, da es vollständig reaktiv ist. Wenn ein Model seinen Zustand ändert, hört das ViewModel zu und übersetzt diesen Zustand und das war's!!! Die View hört dann auf das ViewModel, wenn sich der Zustand ändert, und aktualisiert sich ebenfalls auf der Grundlage der Übersetzung des ViewModels. Manche Leute nennen es reines MVVM, aber es gibt wirklich nur eines, und es ist mir egal, wie man es argumentiert, und es ist immer reines MVVM, bei dem die View absolut keine Logik enthält.
Hier ist ein kleines Beispiel: Nehmen wir an, Sie möchten ein Menü einblenden, wenn Sie eine Taste drücken. In MVC werden Sie eine MenuPressed-Aktion in Ihrer Schnittstelle haben. Der Controller erkennt, wenn Sie auf die Schaltfläche "Menü" klicken, und teilt dann der Ansicht mit, dass das Menü auf der Grundlage einer anderen Schnittstellenmethode wie SlideMenuIn eingeblendet werden soll. Aus welchem Grund eine Umleitung? Für den Fall, dass der Controller entscheidet, dass Sie es nicht können oder stattdessen etwas anderes tun wollen. Der Controller sollte für die View verantwortlich sein und die View sollte nichts tun, es sei denn, der Controller sagt es. JEDOCH; in MVVM sollte das Schiebe-Menü in der Animation eingebaut und generisch sein, und statt gesagt zu werden, um es zu schieben, wird dies auf der Grundlage eines Wertes geschehen. Es hört also auf das ViewModel und wenn das ViewModel sagt, IsMenuActive = true (oder wie auch immer) die Animation für das stattfindet. Nun, mit dem gesagt, ich möchte einen weiteren Punkt wirklich klar und BITTE beachten. IsMenuActive ist wahrscheinlich BAD MVVM oder ViewModel Design. Wenn man ein ViewModel entwirft, sollte man nie davon ausgehen, dass eine View überhaupt irgendwelche Funktionen hat und nur den Status des übersetzten Modells übergeben. Wenn Sie sich also entscheiden, Ihre Ansicht zu ändern, um das Menü zu entfernen und die Daten/Optionen auf andere Weise anzuzeigen, ist das dem ViewModel egal. Wie würden Sie also das Menü verwalten? Wenn die Daten sinnvoll sind, dann so. Eine Möglichkeit ist, dem Menü eine Liste von Optionen zu geben (wahrscheinlich ein Array von inneren ViewModels). Wenn diese Liste Daten enthält, weiß das Menü, dass es über den Trigger geöffnet werden soll, wenn nicht, weiß es, dass es über den Trigger ausgeblendet werden soll. Sie haben einfach Daten für das Menü oder nicht im ViewModel. Entscheiden Sie NICHT, diese Daten im ViewModel ein- oder auszublenden, sondern übersetzen Sie einfach den Zustand des Models. Auf diese Weise ist die Ansicht vollständig reaktiv und generisch und kann in vielen verschiedenen Situationen verwendet werden.
All dies macht wahrscheinlich absolut keinen Sinn, wenn Sie nicht bereits zumindest ein wenig vertraut mit der Architektur der einzelnen und lernen es kann sehr verwirrend sein, wie Sie viele schlechte Informationen auf dem Netz zu finden.
Also... Dinge, die man beachten sollte, um dies richtig zu machen. Entscheiden Sie im Voraus, wie Sie Ihre Anwendung gestalten wollen, und halten Sie sich daran.
Wenn Sie MVC tun, was großartig ist, dann stellen Sie sicher, dass Sie Controller ist überschaubar und in voller Kontrolle über Ihre Ansicht. Wenn Sie eine große Ansicht haben, sollten Sie in Erwägung ziehen, der Ansicht Steuerelemente hinzuzufügen, die verschiedene Controller haben. Lassen Sie diese Controller jedoch nicht in verschiedene Controller kaskadieren. Die Wartung ist sehr frustrierend. Nehmen Sie sich einen Moment Zeit und entwerfen Sie die Dinge separat, so dass sie als separate Komponenten funktionieren... Und lassen Sie immer den Controller dem Modell sagen, dass es den Speicher festschreiben oder persistieren soll. Das ideale Abhängigkeits-Setup für MVC in ist Ansicht Controller Modell oder mit ASP.NET (lassen Sie mich nicht damit anfangen) Model-View-Controller-Model (wobei Model das gleiche oder ein völlig anderes Model als Controller und View sein kann) ...natürlich ist die einzige Notwendigkeit, den Controller in der View zu kennen, an diesem Punkt hauptsächlich für die Endpunktreferenz, um zu wissen, wohin man ein Model zurückgeben muss.
Wenn Sie MVVM tun, segne ich Ihre gute Seele, aber nehmen Sie sich die Zeit, es RICHTIG zu machen! Verwenden Sie keine Schnittstellen für eine. Lassen Sie Ihre View entscheiden, wie sie auf Basis von Werten aussehen soll. Spielen Sie mit der View mit Mock-Daten. Wenn Sie am Ende eine View haben, die Ihnen ein Menü anzeigt (wie im Beispiel), obwohl Sie es zu dem Zeitpunkt nicht wollten, dann GUT. Ihre Ansicht funktioniert, wie sie sollte und reagiert auf der Grundlage der Werte, wie sie sollte. Fügen Sie einfach ein paar weitere Anforderungen an Ihren Trigger hinzu, um sicherzustellen, dass dies nicht passiert, wenn sich das ViewModel in einem bestimmten übersetzten Zustand befindet, oder befehlen Sie dem ViewModel, diesen Zustand zu leeren. In Ihrem ViewModel entfernen Sie dies 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 es im ViewModel ein Menü gibt oder nicht. Und schließlich sollte das Model Ihnen nur erlauben, den Zustand zu ändern und höchstwahrscheinlich zu speichern. Hier findet die Validierung und alles andere statt; wenn das Model beispielsweise den Zustand nicht ändern kann, wird es sich einfach als schmutzig oder so markieren. Wenn das ViewModel dies erkennt, wird es übersetzen, was schmutzig ist, und die View wird dies dann erkennen und einige Informationen über einen anderen Trigger anzeigen. Alle Daten in der View können an das ViewModel gebunden werden, so dass alles dynamisch sein kann, nur das Model und das ViewModel haben absolut keine Ahnung, wie die View auf die Bindung reagieren wird. Tatsächlich hat das Model auch keine Ahnung von einem ViewModel. Beim Einrichten von Abhängigkeiten sollten sie so und nur so zeigen Ansicht ViewModel Model (und eine Randbemerkung hier... und das wird wahrscheinlich auch bestritten werden, aber das ist mir egal... ÜBERGEBEN SIE DAS MODELL NICHT an die VIEW, es sei denn, das MODELL ist unveränderlich; andernfalls verpacken Sie es mit einem richtigen ViewModel. Die View sollte kein Model sehen, Punkt. Ich gebe einen Rattenschwanz darauf, welche Demo Sie gesehen haben oder wie Sie es gemacht haben, das ist falsch).
Hier ist mein letzter Tipp... Schauen Sie sich eine gut gestaltete, aber sehr einfache MVC-Anwendung an und machen Sie dasselbe mit einer MVVM-Anwendung. Die eine wird mehr Kontrolle mit begrenzter bis gar keiner Flexibilität haben, während die andere keine Kontrolle und unbegrenzte Flexibilität hat.
Eine kontrollierte Umgebung eignet sich gut für die Verwaltung der gesamten Anwendung von einer Reihe von Controllern oder (einer einzigen Quelle) aus, während eine reaktive Umgebung in separate Repositories aufgeteilt werden kann, ohne dass man überhaupt weiß, was der Rest der Anwendung tut. Mikroverwaltung vs. freie Verwaltung.
Wenn ich Sie nicht genug verwirrt habe, versuchen Sie, mich zu kontaktieren... Es macht mir nichts aus, dies im Detail mit Illustrationen und Beispielen zu erläutern.
Letzten Endes sind wir alle Programmierer und damit lebt die Anarchie in uns, wenn wir programmieren... Es werden also Regeln gebrochen, Theorien geändert, und all das ist am Ende nur noch Makulatur... Aber wenn man an großen Projekten und in großen Teams arbeitet, hilft es wirklich, sich auf ein Entwurfsmuster zu einigen und es durchzusetzen. Eines Tages werden sich die kleinen zusätzlichen Schritte, die am Anfang gemacht werden, später als große Einsparungen erweisen.
78 Stimmen
Beachten Sie, dass MVVM zwar von Microsoft geprägt wurde, aber auch viele Entwickler und Projekte außerhalb von Microsoft begonnen haben, dieses Muster zu übernehmen. Dieser Kommentar wurde Ihnen von der Abteilung "spite-the-MS-haters" zur Verfügung gestellt.
3 Stimmen
Nachdem ich lange Zeit mit MVVM gearbeitet habe, war meine erste Begegnung mit MVC frustrierend, bis ich lernte, dass ich ViewModels mit Hilfe von Bindungstechniken, die in MVVM zu finden sind, hin und her an den Browser übergeben kann. Aber wie Joel oben sagte, ist der einzige Weg, um den Zustand vom Browser zurückzubekommen, das Posten der Änderungen in einem Formular (das Name/Wert-Paare verwendet). Wenn Sie diesen Punkt nicht gut verstehen. Sie werden eine harte Zeit in MVC haben. Betrachten Sie den Controller einfach als einen Dependency Injector für die View und Sie sind bereit.
6 Stimmen
Eine solche Frage zu hochrangigen [Entwurfsmustern]. Ich würde gerne die Verwendung von Diagrammen in den Antworten vorschlagen.
1 Stimmen
Außerdem wurde die Frage umformuliert, um der Tatsache Rechnung zu tragen, dass die Frage im Zusammenhang mit Microsoft-Technologien gestellt wird... obwohl die akzeptierte Antwort irgendwie nicht stimmt.
5 Stimmen
Hier ist eine archivierte Version von Joels Artikel: web.archive.org/web/20150219153055/http://joel.inpointform.net/
4 Stimmen
Anders als bei der MVC-Methode ist das ViewModel kein Controller. Stattdessen fungiert es als Binder, der Daten zwischen View und Model bindet. Während das MVC-Format speziell darauf ausgelegt ist, eine Trennung von Modell und Ansicht zu schaffen, ist das MVVM-Format mit Datenbindung speziell darauf ausgelegt, dass Ansicht und Modell direkt miteinander kommunizieren können. hackernoon.com/