Richtiges Model-View -_____ Design


14

Ich habe über Model View Controller, Model View Presenter, Model View ViewModel usw. nachgelesen, und im Allgemeinen scheint das zugrunde liegende Konzept ziemlich einfach zu verstehen: Halten Sie die hübschen visuellen und wissenschaftlichen Eingeweide so getrennt und ignorant voneinander wie möglich. Keine logische Erdnussbutter in der Designschokolade; cool, das gefällt mir.

Das Problem ist, dass ich in Bezug auf diesen dritten Teil immer noch ein bisschen unsicher bin ... den, der nicht als Modell oder Ansicht zu sehen ist. Jeder scheint seine eigene Vorstellung davon zu haben, wie er es nennen soll, was es tun soll, was richtig ist, was einfach falsch ist ... und ich bin verrückt, wenn ich herausfinden will, wann ein Presenter ein ViewModel wird und wann ein View nicht ' tu das nicht, weil das der Job des Moderators ist und--

Ich streife.

Anstatt jemanden zu bitten, den Unterschied zwischen ihnen zu erklären - weil das schon immer wieder gemacht wurde (ich weiß, ich habe mehr Artikel gelesen, als ich zählen kann) -, wäre ich neugierig, die Gedanken von a zu hören Nur wenige Programmierer des Modells haben sich zusammengeschustert.

Das heißt, was würden Sie diesen Entwurf als klassifizieren, und was vielleicht noch wichtiger ist, sehen Sie etwas, das offensichtlich scheiße ist? Sicher, ich würde gerne hören, dass es mir gut geht, wenn dies wirklich solides Design ist, aber ich würde viel lieber solide Ratschläge über Lob erhalten.

Hinweis: Ich werde "the Bridge" für den mysteriösen dritten Teil von Model-View-? unbewusste Vorschläge zu vermeiden, was es sein sollte.

Modell

  • Ist die Autorität auf Daten.
  • Erhält Informationen zu angeforderten Änderungen von der Bridge.
  • Enthält und führt die gesamte Logik für die Beziehung zwischen Daten und anderen Daten aus.
  • Informiert die Bridge, wenn sich Daten ändern (für Daten, an denen die Bridge Interesse gezeigt hat). Textbearbeitung: Ermöglicht externen Teilnehmern (von denen sie nichts wissen), den Status oder die Berechnungsergebnisse zu überwachen.
  • Hat keine Kenntnis der Ansicht.

Aussicht

  • Befasst sich mit der Bereitstellung einer Möglichkeit für den Benutzer, Daten anzuzeigen und zu bearbeiten.
  • Erhält Informationen zu Datenaktualisierungen von der Bridge.
  • Enthält und führt die gesamte Logik für die Präsentation von Daten und Steuerelementen für den Benutzer aus.
  • Informiert die Bridge, wenn der Benutzer eine Aktion ausgeführt hat, die (möglicherweise) Auswirkungen auf das Modell hat.
  • Informiert die Brücke darüber, an welchen Informationen sie interessiert ist.
  • Hat keine Kenntnis des Modells.

Brücke

  • Ist der Koordinator und Übersetzer zwischen dem Modell und der Ansicht.
  • Ändert die Formatierung der Informationen, die zwischen dem Modell und der Ansicht übertragen werden.
  • Erhält Informationen zu "Wer muss was wissen".
  • Kennt sowohl das Modell als auch die Ansicht.

Zusätzliche Bemerkungen

  • In komplizierteren Programmen gibt es häufig mehrere Modelle. In dieser Situation übernimmt die Bridge in der Regel die Koordinierung / Übersetzung zwischen den verschiedenen Modellen und wird so zur Autorität dafür, für welche Protocall- / API- / Design-Modelle sie erstellt werden soll. (Wenn Sie z. B. ein Kartenspielprogramm erstellen und ein alternatives Deck-Shuffling-Modell erstellen möchten, sollten Sie mithilfe der Bridge ermitteln, welche Funktionen für eine ordnungsgemäße Kommunikation mit der Bridge erforderlich sind.)
  • In kleinen einfachen Programmen mit nur einer Ansicht und einem Modell "nimmt" die Bridge häufig an, welche Funktionen auf beiden Seiten verfügbar sind. Da Programme jedoch komplexer werden, wird empfohlen, dass die Ansicht (en) und das Modell (en) ihre Funktionalität an die Bridge melden, um Ineffizienzen und fehlerhafte Annahmen zu vermeiden.

Ich denke, das deckt es fast ab. Ich freue mich auf jeden Fall über Ihre Fragen zu dem Design, das ich tendenziell verwende, und ermutige Sie ebenfalls zu Vorschlägen.

Und wie immer vielen Dank für Ihre Zeit.


2
Der View-Block hat einen Copy-Paste-Fehler. Ich denke, die letzte Kugel sollte lauten: "Hat keine Kenntnis des Modells." Und der letzte Satz der 1. Zusatznote sollte wohl mit "Modell" enden, nicht mit "Brücke" ??
Johannes S.

Antworten:


7

Deine Phrase

"Ist der Koordinator und Übersetzer zwischen dem Modell und der Ansicht."

Gibt an, dass Ihre Bridge der Presenter in einer MVP-Architektur ist.

MVP und MVC sind sich sehr ähnlich, mit der Ausnahme, dass in MVP nur der Presenter das Modell beobachtet, während in MVC die Ansicht das Modell auch direkt beobachten kann (ohne den Presenter als "Brücke").

Ihre Modelverantwortung

"Informiert die Bridge, wenn sich Daten ändern (für Daten, an denen die Bridge Interesse gezeigt hat)."

ist möglicherweise falsch formuliert oder ein Fehler: Sie möchten nicht, dass das Modell von Bridge / Presenter / Controller oder View abhängig ist. Stattdessen verwenden Sie entweder ein Observer-Muster, Events oder Reactive Programming, um der Bridge das Abonnieren zu ermöglichen Änderungen im Modell . Und dann können Sie Ihre Verantwortung umformulieren als:

"Ermöglicht externen Teilnehmern (von denen sie nichts wissen), den Status oder die Berechnungsergebnisse zu überwachen."

Wenn Ihr Modell keine Abhängigkeiten von Ihrem Controller oder Ihrer Ansicht aufweist, ist es einfacher zu testen und wesentlich portabler.


1
Wenn der Hauptunterschied darin besteht, dass die Ansicht das Modell beobachten kann oder nicht, dann ist das Design definitiv mehr MVP. Die Ansicht und das Modell dürfen niemals direkt in dem von mir verwendeten Design sprechen.
KoratDragonDen

Die Modellverantwortung war, glaube ich, schlecht formuliert. Das Model hat keine Ahnung, wer / was / warum von Dingen, die es hören möchten, und interessiert sich nicht dafür, sondern veröffentlicht einfach alle Änderungen, die an seinen Abonnenten vorgenommen wurden. Es ist vollkommen zufrieden, ohne Abonnenten jeglicher Art allein zu existieren, und es werden keine Versuche unternommen, neue Abonnenten zu gewinnen.
KoratDragonDen

1
Klingt dann so, als hättest du ein gutes Design. PS Der Grund, MVC gegenüber MVP in Betracht zu ziehen, besteht darin, dass der Präsentator ohne Disziplin überlastet werden kann.
Larry OBrien

1
+1 für die einfache Angabe des Unterschieds zwischen MVC und MVP. Wie bei OP hat mich der Rest des Internets völlig enttäuscht, ob diese Akronyme auch nur ein bisschen anders waren.
Ixrec

5

Ich vermute, eines der Dinge, die Sie verwirren, ist, dass es zwei völlig verschiedene Muster gibt, die beide allgemein als Model-View-Controller bezeichnet werden.

Es gibt das Original, wie es in Smalltalk implementiert ist und das für lokale GUI-Systeme nützlich ist, und es gibt das, was ich als Web-MVC bezeichne, das einige der Verantwortlichkeiten von Ansichten und Controllern vertauscht, damit Controller auf dem Server sitzen können Ansichten sind auf dem Client (vielleicht als HTML gerendert, oder vielleicht über Ajax).

Ihre Beschreibung klingt für mich so, als würde sie in die meisten Definitionen von Web-MVC passen.


Das könnte erklären, warum ich so viel Mühe hatte, mich um das Konzept zu kümmern. Vielen Dank; Es ist gut zu wissen, dass ich (wahrscheinlich) nichts schrecklich Falsches mit dem Konzept von MVC tue.
KoratDragonDen

Bei modernen einseitigen Webanwendungen greifen wir auf der Clientseite auf das klassische MVC-Muster zurück.
Kevin Cline

2

Über diese genaue Nomenklatur wird in der Programmierszene viel diskutiert. Über vieles scheint sich niemand einig zu sein.

Die Art und Weise, wie die Brücke mit der Ansicht verbunden ist, bestimmt für mich hauptsächlich den Namen.

  • Wenn es pro Bridge eine Sammlung von Ansichten geben kann, ist die Bridge ein Controller.
  • Wenn es immer eine Ansicht pro Brücke gibt, ist die Brücke ein Präsentator.
  • Wenn es pro Ansicht eine Sammlung von Brücken geben kann, ist die Brücke ein Ansichtsmodell.

Manchmal sind die Dinge nicht so klar. Beispielsweise könnte ein Präsentator mit einer zusammengesetzten Ansicht aus mehreren Unteransichten verbunden sein, oder ein Controller könnte ohne Kenntnis seiner Ansichten erstellt werden. Trotzdem denke ich, dass meine Regeln ein guter Anfang sind.


Als Randnotiz möchte ich die Verantwortlichkeiten wie folgt zusammenfassen:

Modell

Hauptverantwortung: Daten beibehalten
Nebenrollen: Aktualisierungen validieren, Beobachter über Aktualisierungen benachrichtigen

Aussicht

Hauptverantwortung: Daten präsentieren
Nebenrollen: Eingaben akzeptieren, UX präsentieren

Brücke

Hauptverantwortung: Daten
aktualisieren Nebenrollen: Eingaben bereinigen, Daten und Ansichten synchronisieren


0

Obwohl Ihr vorgeschlagenes Muster oberflächlich korrekt zu sein scheint und bei kleinen Instanzen zweifellos funktionieren wird, wenn Ihre App komplexer wird, treten Probleme auf, bei denen Sie sich nicht sicher sind, was aktualisiert wird, wer wo zuhört und warum ich es versuche um so viele Models von so vielen Views aus zu steuern, die alle aufeinander zugreifen müssen, etc.

Ich empfehle, Ihre Ideen anhand des folgenden Musters zu erweitern (aus Amy Palamounts Vortrag Enemy of the State ):

Modelle

  • Synchronisieren Sie den Status mit dem Datenspeicher
  • Verarbeiten Sie die Validierung neuer / aktualisierter Daten
  • Ereignisse auslösen, wenn sie den Status ändern

Ansichten

  • Vorlagen rendern
  • Behandeln von Modellereignissen
  • Behandeln von DOM-Ereignissen
  • Vermittelt die Interaktion zwischen Model und DOM

Controller

  • Verwaltet höchstens ein Paar Models & Views
  • Verfolgt Ansichten in einem Container

Module

  • Die logische Gruppierung eines Controllers und seiner Ansichten und Modelle
  • Testbar
  • Klein und wartbar (Einzelverantwortung)
  • Koordiniert (über den Controller) den Status und die Ereignisse der darin enthaltenen Ansichten und Modelle
  • Geben Sie frei, um seine eigenen Ansichten zu präsentieren
  • Nicht frei zu wählen, wo seine Ansichten zu präsentieren

Layout Manager

  • Verantwortlich für die Layoutgestaltung
  • Definiert eine Anwendungsshell im DOM mit Bereichen, in denen Module ihren Inhalt präsentieren können

Dispatcher

  • Ereignisse abhören (über globalen PubSub-Stream)
  • Verantwortlich für das Laden neuer Module basierend auf Events
  • Übergibt geladene Module an den Layout Manager
  • Verwaltet die gesamte Lebensdauer des Moduls (Erstellung, Bereinigung, Zwischenspeicherung usw.)
  • Veranstaltungsbeispiele:
    • Routenänderungen (einschließlich anfänglicher Laderoute)
    • Benutzerinteraktion
    • Das Modulereignis ist aufgrund einer serverseitigen Statusänderung usw. Aus einem Modellereignis gesprudelt

Anwendung

  • Instantiiert Dinge wie:
    • Dispatcher
    • Router
    • PubSub-Stream
    • Logger
    • etc

Diese Art von Muster ermöglicht es Ihrer Anwendung, komponierbar zu sein, eine Einheit zu testen, die Komplexität zu beseitigen, die eine Bridge im Laufe der Zeit aufbauen würde, Probleme schön voneinander zu trennen usw.

Wie Amy betont: Achten Sie darauf, keinen Server auf dem Client zu erstellen. Und passen Sie auf, dass Sie nicht in die Doktrin "Ich erstelle ein MV * -Framework, deshalb muss ich ___!" Nehmen Sie stattdessen all diese Ideen (und die anderen Antworten hier) und finden Sie heraus, was für Ihre Anwendung und Ihr Team am besten geeignet ist.

Ich empfehle dringend, Amy Palamountain 's Vortrag Enemy of the State (aus dem diese Ideen hervorgegangen sind) zu sehen oder zumindest die Folien des Vortrags zu überblicken .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.