1478 Stimmen

Was ist der Unterschied zwischen MVC und MVVM?

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

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

18voto

DaniCE Punkte 2332

Das Viewmodel ist ein "abstraktes" Modell für die Elemente Ihrer Benutzeroberfläche. Es muss es Ihnen ermöglichen, die Befehle und Aktionen in Ihrer Ansicht auf nicht-visuelle Weise auszuführen (z. B. um sie zu testen).

Wenn Sie mit MVC gearbeitet haben, haben Sie es wahrscheinlich schon einmal als nützlich empfunden, Modellobjekte zu erstellen, die den Zustand Ihrer Ansicht widerspiegeln, z. B. um einen Bearbeitungsdialog ein- und auszublenden usw. In diesem Fall verwenden Sie ein Viewmodel.

Das MVVM-Muster ist einfach die Verallgemeinerung dieser Praxis auf alle UI-Elemente.

Und es ist nicht ein Microsoft-Muster, was hinzukommt ist, dass WPF / Silverlight Daten-Bindungen sind besonders gut geeignet, um mit diesem Muster zu arbeiten. Aber nichts hindert Sie daran, es mit Java Server Faces, zum Beispiel zu verwenden.

14voto

Cheng Punkte 562

Es erstaunt mich, dass dies eine hochrangige Antwort ist, ohne dass man die Herkunft von MVVM. MVVM ist ein beliebter Begriff in der Microsoft-Community und wird entstanden ist. aus dem Buch von Martin Fowler Präsentation Modell . Um also das Motiv des Musters und die Unterschiede zu anderen Mustern zu verstehen, sollte man zunächst den Originalartikel über das Muster lesen.

0 Stimmen

Wow... also stammen sowohl MVC als auch MVVM von SmallTalk? Sie waren anscheinend ihrer Zeit weit voraus...

0 Stimmen

Die Behauptung, es stamme aus dem Präsentationsmodell von Martin Fowler, ist nicht ganz richtig. Es ist sehr schwierig zu bestimmen, was zuerst da war, aber beide Muster (wenn man davon ausgeht, dass es sich wirklich um das gleiche Muster handelt) wurden unabhängig voneinander und ungefähr zur gleichen Zeit entwickelt.

10voto

JWP Punkte 6290

Injektion von stark typisierten ViewModels in die View mit MVC

  1. Der Controller ist dafür verantwortlich, das ViewModel zu erstellen und es in die View zu injizieren. (für Get-Anfragen)
  2. Das ViewModel ist der Container für den DataContext und den View-Status, wie z. B. das zuletzt ausgewählte Element usw.
  3. Das Modell enthält DB-Entitäten und ist sehr nah am DB-Schema, das die Abfragen und Filterung vornimmt. (Ich mag EF und LINQ für diese Aufgabe)
  4. Das Modell sollte auch Repositories und/oder die Projektion von Ergebnissen in starke Typen berücksichtigen (EF hat eine großartige Methode... EF.Database.Select(querystring, parms) für direkten ADO-Zugriff, um Abfragen zu injizieren und starke Typen zurückzubekommen. Dies spricht das Argument an, dass EF langsam ist. EF ist NICHT LANGSAM !
  5. Das ViewModel erhält die Daten und führt die Geschäftsregeln und die Validierung durch
  6. Der Controller auf zurücksenden ruft die ViewModel Post-Methode auf und wartet auf Ergebnisse.
  7. Der Controller wird das neu aktualisierte Viewmodel in die View injizieren. Die View verwendet nur starke Schriftbindung .
  8. Der View rendert lediglich die Daten und gibt Ereignisse an den Controller zurück. (siehe Beispiele unten)
  9. MVC fängt die eingehende Anfrage ab und leitet sie an den richtigen Controller mit starker Datentyp

In diesem Modell gibt es keine HTTP-Ebene mehr Kontakt mit den Anfrage- oder Antwortobjekten, da die MVC-Maschine von MSFT sie vor uns verbirgt.

Zur Erläuterung von Punkt 6 oben (auf Anfrage)...

Nehmen Sie ein ViewModel wie dieses an:

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 dann so aus (siehe unten). Beachten Sie, dass die Instanz von mvm automatisch durch die MVC-Bindungsmechanismen instanziiert wird. Sie müssen nie auf die Abfrage-String-Schicht als Ergebnis fallen! MVC instanziert das ViewModel für Sie auf der Grundlage der Query Strings!

[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 actionmethod oben zu arbeiten, wie Sie beabsichtigen, müssen Sie eine null CTOR definiert, die Dinge nicht in der Post zurückgegeben intialisiert. Der Postback muss auch Name/Wert-Paare für die Dinge zurückgeben, die sich geändert haben. Wenn Name/Wert-Paare fehlen, tut die MVC-Bindungs-Engine das Richtige, nämlich einfach nichts! Wenn das passiert, werden Sie sich vielleicht sagen: "Ich verliere Daten bei Post Backs"...

Der Vorteil dieses Musters besteht darin, dass das ViewModel die gesamte "unübersichtliche" Arbeit mit der Model-/Business-Logik übernimmt, der Controller ist lediglich eine Art Router. Es ist SOC in Aktion.

1 Stimmen

Können Sie Punkt 6 erläutern? Mir ist klar, dass Sie nur ASP.Net abdecken, aber es scheint, dass eine unerwünschte Abhängigkeit zum ViewModel hinzugefügt wird. (z.B. das Wissen, woher die Daten kommen und wohin sie gehen). Ein Codebeispiel (Pseudocode?) wäre gut, um diese Antwort zu verdeutlichen und zu zeigen, welche Teile serverseitig und welche clientseitig sind.

10voto

ScottyBlades Punkte 9468

MVVM

  1. Ansicht ViewModel Model
  • Die Ansicht hat einen Verweis auf das ViewModel, aber nicht umgekehrt.
  • Das ViewModel hat einen Verweis auf das Model, aber nicht andersherum.
  • Die Ansicht hat keinen Verweis auf das Modell und umgekehrt.
  1. Wenn Sie einen Controller verwenden, kann dieser einen Verweis auf Ansichten y AnsichtenModelle obwohl ein Controller nicht immer notwendig ist, wie in SwiftUI .
  2. Daten Bindung : Wir erstellen Listener für ViewModel-Eigenschaften, so dass Daten von der Ansicht zum Modell über das Ansichtsmodell fließen können. Während die Referenzen in eine Richtung gehen: View ViewModel Model, müssen die Daten fließen: Ansicht AnsichtModell Modell. Es ist klar, wie die Ansicht Daten aus dem Modell erhält, indem sie ihre eigenen Eigenschaften liest. Data Binding ist die Art und Weise, wie Ereignisse innerhalb der Ansicht erkannt und an das Modell zurückgegeben werden.

    class CustomView: UIView { var viewModel = MyViewModel { didSet { self.color = viewModel.viewColor } }

    convenience init(viewModel: MyViewModel) { self.viewModel = viewModel } }

    struct MyViewModel { var viewColor: UIColor { didSet { colorChanged?() // This is where the binding magic happens. } }

    var colorChanged: ((UIColor) -> Void)? }

    class MyViewController: UIViewController {

    let myViewModel = MyViewModel(viewColor: .green) let customView: CustomView!

    override func viewDidLoad() { super.viewDidLoad()

      // This is where the binder is assigned.
      myViewModel.colorChanged = { [weak self] color in 
        print("wow the color changed")
      }
      customView = CustomView(viewModel: myViewModel)
      self.view = customView

    } }

Unterschiede im Aufbau

  1. Die Geschäftslogik befindet sich bei MVC im Controller und bei MVVM in den ViewModels.
  2. In MVC werden Ereignisse direkt von der View an den Controller übergeben, während in MVVM Ereignisse von der View an das ViewModel an den Controller (falls vorhanden) übergeben werden.

Gemeinsame Merkmale

  1. Sowohl MVVM als auch MVC erlauben es der View nicht, Nachrichten direkt an das/die Model/s zu senden.
  2. Beide haben Modelle.
  3. Beide haben Ansichten.

Vorteile von MVVM

  1. Da die ViewModels die Geschäftslogik enthalten, sind sie kleinere konkrete Objekte, die sich leicht in Unit-Tests testen lassen. Im Gegensatz dazu befindet sich bei MVC die Geschäftslogik im ViewController. Wie kann man sich darauf verlassen, dass ein Unit-Test eines ViewControllers umfassend sicher ist, ohne alle Methoden und Listener gleichzeitig zu testen? Man kann den Ergebnissen der Unit-Tests nicht ganz trauen.
  2. Da bei MVVM die Geschäftslogik aus dem Controller in atomare ViewModel-Einheiten ausgelagert wird, schrumpft die Größe des ViewControllers, wodurch der ViewController-Code besser lesbar wird.

Vorteile von MVC

  1. Durch die Bereitstellung von Geschäftslogik innerhalb des Controllers wird die Notwendigkeit von Verzweigungen verringert, und daher werden Anweisungen eher im Cache ausgeführt, was leistungsfähiger ist als die Kapselung von Geschäftslogik in ViewModels.
  2. Die Bereitstellung der Geschäftslogik an einer Stelle kann den Entwicklungsprozess für einfache Anwendungen beschleunigen, für die keine Tests erforderlich sind. Ich weiß nicht, wann Tests nicht erforderlich sind.
  3. Die Bereitstellung von Geschäftslogik im ViewController ist für neue Entwickler einfacher zu denken.

4 Stimmen

Beste Erklärung

9voto

se_thoughts Punkte 91

Soweit ich das beurteilen kann, entspricht MVVM dem MV von MVC - was bedeutet, dass in einem traditionellen MVC-Muster das V nicht direkt mit dem M kommuniziert. In der zweiten Version von MVC gibt es eine direkte Verbindung zwischen M und V. MVVM scheint alle Aufgaben zu übernehmen, die mit der Kommunikation zwischen M und V zusammenhängen, und sie von der C zu entkoppeln. Dies ist die Rolle des Controllers. Durch das Entfernen dieser untergeordneten Aspekte aus den Controllern sind diese sauberer und es ist einfacher, das Anwendungsszenario und die Geschäftslogik der Anwendung zu ändern, was auch die Wiederverwendbarkeit der Controller erhöht.

1 Stimmen

IMHO würde ich argumentieren, dass "Controller wiederverwendbarer machen" eine zu weit gefasste Aussage ist und für allgemeine ASP.Net-"Controller" (d.h. nicht die Geschäftslogikschicht) kontraproduktiv ist, da diese Controller normalerweise die Teile der Anwendung enthalten, die anwendungsspezifisch . Es sind die Views, Models, ViewModels und die Geschäftslogik, die wiederverwendbar sein müssen. Ich hätte gedacht, dass die Behandlung der Geschäftslogik-Module als Dienstanbieter und nicht als Controller eine bessere Option wäre.

0 Stimmen

Aber Sie sprechen über das "ViewModel" in Asp.net, nicht über das MVVM-Designmuster. Das sind zwei verschiedene Dinge.

CodeJaeger.com

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

Powered by:

X