Sollte ein Modell in MVC Unteransichtsmodelle enthalten?

8

Einige Hintergrundinformationen:

Ein Kollege und ich haben unterschiedliche Interpretationen von MVC, was bedeutet, dass wir angesichts des gleichen Problems radikal unterschiedliche Lösungen finden. Er stammt aus einem Java-Hintergrund, in dem jede Komponente von MVC traditionell ein Objekt modelliert, und ich komme aus einem Haskell-Hintergrund und habe wenig oder keine Erfahrung mit OOP.

Der Problembereich:

Das Problem, das wir zu modellieren versuchen, verhält sich ein wenig wie eine Desktop-Umgebung. Wir haben eine Vorstellung von der Benutzersitzung (möglicherweise ihrem Login, ihrem Desktop-Hintergrund) und den Prozessen auf ihrem Desktop (z. B. iTunes, Finder usw.), die jeweils ihre eigenen Modelleigenschaften haben (minimiert usw.).

Wir sind uns in folgendem Punkt einig: Wir halten HMVC für die beste Vertretung. Wir sind uns einig, dass wir zwei MVC-Objekte haben Session(Desktop) und Process(Anwendung) und dass wir nicht möchten Process, dass ein Objekt eine Vorstellung von Sessionoder ein Backlink hat.

Sobald wir uns nicht einig sind, ist die Kernbedeutung von MVC und wie sich dies darauf auswirkt, wo wir die Liste der Prozesse auf dem Desktop des Benutzers aufbewahren .

Seine Interpretation:

Er argumentiert einen sehr gültigen Punkt, der traditionell einfach im Code und in unserem Rendering-System zu modellieren ist. Er sagt, dass die Liste der Prozesse eine Liste von ProcessControllerObjekten sein sollte, in SessionControllerdenen sich ihre Modelle wiederum als separate Objekte befinden. Dies bedeutet , dass es eine erhebliche Menge an Staat innerhalb der beiden ist SessionControllerund SessionModeldas ist relevant, was SessionViewbraucht zu machen.

Dies scheint sehr im Einklang mit dem zu stehen, was wir in einer kurzen Suche im Internet lesen konnten.

Meine Interpretation:

Meine Interpretation erfordert die größte architektonische Änderung und scheint schwieriger im Code zu implementieren, aber ich glaube, dass sie konzeptionell korrekter ist. Ich möchte, dass jemand erklärt, warum dies nicht der Fall ist, oder ein anderes Modell (wenn nicht MVC) vorstellt, das mit dieser Interpretation übereinstimmt, und einige Stärken und Schwächen für beide Muster hervorhebt, damit wir die fundierteste Entscheidung treffen können (keiner von uns hat dies getan) ein starker Hintergrund in der Softwarearchitektur).

Ich sehe MVC als Triade mit drei austauschbaren Komponenten: der Model, der Controllerund der View. Dies stimmt mit dem überein, was ich im Internet lesen kann, und einige Quellen sagen Dinge wie "Ansichten, Controller und Modelle mit derselben Schnittstelle sollten zu unterschiedlichen Effekten austauschbar sein". Ich stelle mir das so vor:

  • Wenn Sie das Modell austauschen, ändern Sie die Art und Weise, wie Daten validiert oder gespeichert werden
  • Wenn Sie den Controller austauschen, ändern Sie , wie Sie die Seite verhält sich , aber nichts, das die c verändern könnten onceptual Dateninhalt der Seite
  • Wenn Sie die Ansicht tauschen, ändern Sie die Art und Weise, wie die Seite angezeigt wird

Aus diesem Grund bin ich zu dem Schluss gekommen, dass bei einem Modelund Viewnur beim Austausch des Controllers die Daten, die die Seite anfänglich rendert, nicht geändert werden sollten, da der Controller nur das Verhalten und nicht den 'Inhalt' der Seite ändern sollte. Ich denke, dies stimmt mit der konzeptionellen Visualisierung des Controllers als "Stationscontroller" in einem Schienensystem, einem Plan der Eisenbahn als Modell und der tatsächlichen physischen Manifestation und dem Erscheinungsbild der Gleise überein (z. B. in verschiedenen Geschmacksrichtungen). Real 'oder' Virtual 3D ') als Ansicht.

Hier sind wir uns nicht einig:

Ich behaupte, dass, da die Daten, die dem Benutzer in angezeigt werden, SessionViewdurch die verschiedenen Prozesse auf dem Desktop geändert werden (ich modelliere die Prozesse als relevante Daten ), SessionModeldie Liste der Instanzen von enthalten sollte ProcessModel. Dies bedeutet, dass die Verwendung eines beliebigen Zufalls SessionControllermit demselben SessionViewKonzept konzeptionell dieselben Daten anzeigen sollte (Prozesse auf dem Desktop).

Er argumentiert, dass es sinnvoller ist Model, nie etwas über ein anderes Modell zu wissen. Dies bedeutet, dass das SessionControllereine Liste von ProcessControllers enthält und jedes ControllerObjekt einen Link zu seinem Modell hat. Bei a SessionViewund gleich, SessionModelaber unterschiedlich sollten SessionControllerdie dem Benutzer angezeigten Daten radikal unterschiedlich sein.

Bitte argumentieren Sie für / gegen jede Interpretation und helfen Sie uns, das bestmögliche Ergebnis zu erzielen.

Vielen Dank für Ihre Zeit!

kvanberendonck
quelle
1
Das Austauschen des Controllers kann dazu führen, dass die Controller-Methode eine andere Ansicht rendert oder ein anderes Objekt zurückgibt. Ihr Argument ist also wahrscheinlich nur dann sinnvoll, wenn der Controller, den Sie austauschen, einer bestimmten Schnittstelle / einem bestimmten Vertrag entspricht. Daher gibt es keine Garantie dafür, dass der neue Controller die gleichen Daten für die Ansicht wiedergibt. Der Controller ist nur verpflichtet, das zu rendern oder zurückzugeben, für das er programmiert ist.
Robert Harvey
Der Einstiegspunkt für das Rendern sollte also der Controller sein und nicht die Ansicht (mit dem Controller als Argument)?
Kvanberendonck
1
Sie, die aus Haskell kommen, sollten sich auf Folgendes beziehen: Ich denke, MVC ist nur ein abstraktes Modell der Beziehungen zwischen Teilen eines Programms, aber welche Teile die Rollenansicht, das Modell oder den Controller spielen sollten, hängt von dem Problem ab, mit dem Sie konfrontiert sind . Ebenso ist die Kategorietheorie nur ein Satz von Regeln, um die Beziehungen zwischen Objekten zu formalisieren, aber es gibt keine starre Definition, welche tatsächlichen Objekte mit diesen Regeln verwendet werden dürfen. CT selbst kann mit CT formalisiert werden. HMVC ist ein gutes Beispiel für diese Idee, da Sie MVC in MVC verwenden können (obwohl es nicht dieselbe Art von Rekursion ist).
Didierc
1
Es gibt auch andere Regeln, die vorschreiben, wie Dinge geschrieben werden sollen: DRY, SOLID, KISS. Sie stehen nicht im Widerspruch zu MVC und sollten auf jeden Fall genauso angewendet werden (wenn nicht mehr).
Didierc

Antworten:

6

Der Schlüssel zum Verständnis von MVC liegt in der Trennung der Verantwortlichkeiten, da MVC einfach SRP ist, das auf UI-Code angewendet wird. Es trennt, welche Daten angezeigt werden müssen, wie sie angezeigt werden und wie Bildschirmereignisse behandelt werden. Ein wichtiges (und oft übersehenes) Detail der ursprünglichen Definition von MVC ist jedoch, dass es für eine weitaus detailliertere Ebene konzipiert wurde. Zum Beispiel hätten Sie ButtonModel-, ButtonView- und ButtonController-Objekte, "nur" um eine einzelne Schaltfläche auf einem Bildschirm darzustellen. Das Fehlen dieses Details führt zu so vielen unterschiedlichen Meinungen zu diesem Thema. Sie können die Java Swing-Architektur überprüfen, um zu sehen, was ich meine.

Der Zweck von MVC besteht darin, zu ermöglichen, dass der Code, der jeder Verantwortung dient, geändert wird, ohne den Code für die anderen zu beeinflussen. Sie können beispielsweise das Rendern (einer Komponente auf dem Bildschirm) umschalten, ohne die Datendarstellung oder die Ereignisbehandlungslogik berühren zu müssen. Bis zu einem gewissen Grad stimmt dies mit dem überein, was Sie hier sagen:

Aus diesem Grund habe ich festgestellt, dass bei jedem Modell und jeder Ansicht durch das Austauschen nur des Controllers die Daten, die die Seite anfänglich rendert, nicht geändert werden sollten, da der Controller nur das Verhalten und nicht den 'Inhalt' der Seite ändern sollte. Ich denke, dies stimmt mit der konzeptionellen Visualisierung des Controllers als "Stationscontroller" in einem Schienensystem, einem Plan der Eisenbahn als Modell und der tatsächlichen physischen Manifestation und dem Erscheinungsbild der Gleise überein (z. B. in verschiedenen Geschmacksrichtungen). Real 'oder' Virtual 3D ') als Ansicht.

In Ihrem Kontext ist die Granularität jedoch deaktiviert. Sie haben eine SessionView, die für einen ganzen Bildschirm verantwortlich zu sein scheint. Auf dieser Ebene werden die Verantwortlichkeiten zu stark gekoppelt, um sich wie von MVC beabsichtigt vollständig zu trennen, sodass möglicherweise nicht alle Vorteile erzielt werden.

Ihr Problem besteht darin, die drei Verantwortlichkeiten der Benutzeroberfläche (Rendern, Daten und Ereignisbehandlung) für Sitzungen und Prozesse zu trennen, insgesamt sechs. Aufgrund der Granularität der Komponenten (ganzer Bildschirm) wird dies unmöglich und verursacht die Dissonanz, in die Sie sich befinden.

Sie möchten die Verantwortlichkeiten für das Rendern und die Ereignisbehandlung sowohl für Sitzungen als auch für Prozesse trennen, möchten jedoch deren Daten koppeln. Ihr Kollege möchte die Daten entkoppeln, aber die Ereignisbehandlung koppeln.

Am Ende ist dies also ein SRP-Problem. Mein Ausweg wäre, die Granularität so weit zu verringern, dass Sie Sitzungen klar von Prozessen trennen können. Wenn Sie dies aus wirtschaftlichen Gründen nicht tun können, müssen Sie einfach beide Seiten des Kompromisses abwägen, das am wenigsten schlechteste auswählen und es als technische Verschuldung abzeichnen. Darum geht es schließlich bei Designentscheidungen. :) :)

MichelHenrich
quelle
Vielen Dank für Ihre Zeit und Ihren durchdachten Kommentar. Wir müssen hier viel nachdenken! Ich hoffe, es macht Ihnen nichts aus, wenn ich dies für eine Weile offen lasse, bevor ich eine Antwort wähle, um andere nicht davon abzuhalten, ihre POV zu teilen.
Kvanberendonck
Ich habe heute darüber nachgedacht und bin auf eine interessante Frage gestoßen: Wie sieht das Rendern aus, wenn sich die Prozesse im Sitzungsmodell befinden? Wie erhält eine SessionView Zugriff auf die ProcessController, um sie an die ProcessView weiterzugeben?
Kvanberendonck
1
Mit MVC trennen Sie Sitzungen entweder vollständig von Prozessen (detaillierter als in Ihrem Beispiel) oder Sie erstellen ein einzelnes Modell, eine Ansicht und einen Controller für den gesamten Bildschirm und behandeln Sitzungen und Prozesse als eine große Sache (gröber). Ihr Problem ist die aktuelle Granularität Ihrer Objekte, bei der Sie versuchen, Dinge zu trennen, aber keine saubere Trennung zulässt. Andere Muster wie MVP oder MVVM funktionieren besser für "ganze Bildschirme" als MVC, das für die kleinen Elemente auf dem Bildschirm gedacht ist.
MichelHenrich