Können auf MVC mehrere Ansichten denselben Controller haben oder muss eine Ansicht einen eindeutigen Controller haben?

15

Ich habe einige Fragen beim Entwerfen einer Architektur für ein Projekt rund um MVC. (Es ist ein C ++ / Marmalade SDK-Projekt, ich verwende kein bestimmtes MVC-Framework, ich erstelle eines.)

Auf einigen Artikeln (wie auf dem ursprünglichen Artikel von Steve Burbek ) lese ich immer wieder das Konzept "MVC triad", das mich stört , da ich dieses Konzept wörtlich genommen habe. Als ich es das erste Mal las, sah es so aus, als würde eine Anwendung um "MVC-Triaden" -Einheiten herum erstellt - eine für jedes UI-Teil, das ich angenommen habe -, aber ich finde, dass dies ziemlich unflexibel ist und ich denke, dass MVC nicht so verwendet werden sollte. Als ich mich dann weiter mit dem Thema befasste, fand ich einige Beispiele für eine enge Kopplung zwischen dem Controller und der Ansicht, nämlich eine 1-zu-1-Beziehung. TextEditView verfügt über TextEditController.

Aber wenn ich zu meinem Projekt zurückkehre, kann es nützlich sein, einen Controller (nach 'logischer Einheit' wie AddElementController) und mehrere Ansichten für diesen bestimmten Controller zu haben.

Ich denke eindeutig an so etwas wie einen AddElementController, der eine Art Benutzeroberfläche für Registerkarten haben sollte. Sollte ich einen AddElementController mit einem AddElementTabView und mehreren AddImageView, AddSoundView usw. für die Registerkarten haben? Oder sollte ich für jede Registerkartenansicht einen anderen "Sub-Controller" haben?

In der Summe und in Bezug auf das MVC-Muster (nicht das spezielle Verständnis / die Implementierung dieses Musters im X-Framework) ist es richtig, mehrere Ansichten für einen Controller zu haben, oder sollte jede Ansicht einen bestimmten Controller haben?

Ist es auch richtig, einige Statusinformationen auf dem Controller zu behalten, oder sollte sie zustandslos sein (was bedeutet, dass der Status auf einem Nicht-Domain-Statusmodell platziert werden sollte)?

Vielen Dank an alle im Voraus.

pedrosanta
quelle

Antworten:

14

Das Problem ist, dass das MVC-Muster in einem System entworfen wurde, das nicht mehr wirklich existiert. Es wurde in Smalltalk zu einer Zeit erfunden, als es keine UI-Bibliotheken gab. Um ein Fensterdialogfeld zu erstellen, haben Sie alle Kästchen gezeichnet, die entsprechenden Quadrate markiert und sichergestellt, dass der von Ihnen gezeichnete Text an der richtigen Stelle angezeigt wurde ... etc ...

Stellen Sie sich vor, wie es wäre, eine Dialog-App mit nur einer großen Zeichenfläche zu schreiben. Das ist die Welt, aus der die MVC kommt.

Eine "Ansicht" in diesem System war ein Textfeld und eine Klasse, die für das Zeichnen des Felds, des Texts, das Zeichnen ausgewählter Bereiche, das Reagieren auf Änderungen im Text usw. verantwortlich war.

Ein "Controller" war eine weitere Klasse, die Mausereignisse, die in dieser Box auftraten, wie Mausbewegungen, Herunterfahren, Hochfahren, Klicken usw., aufnahm und darüber entschied, was passierte. Sollen wir den Text ändern? Sollen wir die Auswahl ändern? Solche Sachen.

Ein "Modell" war eine weitere Klasse, die die Basisdaten und den Zustand der Komponente darstellte. Ein Textfeldmodell würde natürlich den Text, die Schriftart, die Auswahl usw. enthalten.

Wie Sie sehen, sind in einer solchen Situation die drei Komponenten stark in der Darstellung einer einzelnen Idee verstrickt. In diesem Zusammenhang ist es sinnvoll, von einer "Triade" zu sprechen.

Wenn Sie heute daran arbeiten, eine UI-Bibliothek zu erstellen und Rohzeichnungsbefehle zu verwenden, können Sie etwas Ähnliches tun. Die Anwendung des "MVC" -Musters hat sich jedoch über seinen ursprünglichen Zweck hinaus verbreitet. Heutzutage haben Sie eine "Ansicht", die tatsächlich ein vollständiger Dialog sein kann, und einen Controller, der auf Ereignisse wie "textChanged" oder "buttonClicked" reagiert. Das Modell in der heutigen MVC ist normalerweise ziemlich vom System getrennt (aber im Allgemeinen mit der Ansicht verbunden, indem eine Art Beobachter-Schnittstelle bereitgestellt wird), und es kann viele Ansichten geben, die mit dem einen Modell verknüpft sind.

In einem kürzlich von mir erstellten System hatten wir zum Beispiel mehr als 10 Ansichten, bei denen alle einen einzelnen "Inhaber" eines Dokuments und sein aktives Dokument betrachteten. Eine Hauptzeichnungsschnittstelle interagierte mit dem Layout des Dokuments, verschiedenen Eigenschaftsansichten, die das ausgewählte Element betrachteten und eine Aufzeichnungsschnittstelle bereitstellten, und einer verkleinerten Darstellung der Hauptansicht, die das gesamte Dokument anstelle nur des sichtbaren Fensters zeigte. Einige dieser Ansichten hatten Controller unterschiedlicher Komplexität, die GUI-Ereignisse in Änderungen am Dokument umwandelten, die wiederum die verschiedenen Ansichten benachrichtigten.

Kann man eine solche Beziehung immer noch als "Triade" bezeichnen? Vielleicht, aber ich denke, es impliziert zu viel von der früheren, älteren Anwendung von MVC.

Könnten Sie Controller mit verschiedenen Ansichten teilen? Hängt davon ab, wie ähnlich die Ansichten sind. Ich habe festgestellt, dass diese Art von Objekt im Allgemeinen ein spezifisches Verhalten für die Ansicht hat, die es steuert, UND für das Modell, das es manipuliert, um sehr wiederverwendbar zu sein ... aber es gibt immer Ausnahmen.

Edward Strange
quelle
5

Es hängt davon ab, ob. Es gibt verschiedene MVC-Varianten, von denen einige nur eine 1: 1-Beziehung sinnvoll machen (wie "das bescheidene Dialogfeld") und andere, bei denen dies nicht der Fall ist. Ich würde empfehlen, die Artikelserie " Build Your Own CAB " zu lesen , in der die wichtigsten MVC-Varianten erläutert werden.

Doc Brown
quelle
3

Views hat keine Controller in MVC. Der Controller ist der Boss, also entscheidet ein Controller, welche Ansicht gerendert werden soll, und Views ist es egal, welcher Controller die Ansicht angefordert hat.

Sie können / werden absolut mehrere Ansichten von einem Controller haben. Denken Sie nur daran, ein Modell für jede Ansicht zu erstellen, wenn Sie das MVC-Muster beibehalten möchten.

Mert Akcakaya
quelle
3

Der Zweck des Controllers besteht darin, die Benutzerinteraktionen mit Ihrem Domain-Modell zu steuern. Dies ist eine Ebene der Indirektion zwischen dem, was der Benutzer sieht (der Ansicht) und dem Status Ihrer Anwendungen (dem Modell).

Wenn der Benutzer eine Anfrage stellt, wird diese an eine Steuerung weitergeleitet. Der Controller entscheidet, wie diese Anforderung an die Anwendung weitergeleitet wird, normalerweise über eine Art Serviceklasse. Anschließend wird die Antwort dieser Serviceklasse interpretiert und entschieden, welche Ansicht an den Benutzer zurückgesendet werden soll.

Ein Controller kann immer dieselbe Ansicht (1: 1) zurückgeben, wenn es nur eine Art von Anforderung gibt, die der Benutzer an den Controller senden kann, und er benötigt immer dieselbe Art von Antwort. Beispielsweise HelloWorldControllerwird immer die HelloWorldViewMeldung "Hello, World!"

Auf der anderen Seite muss sich ein Controller oft für verschiedene Ansichten entscheiden, je nachdem, was das Modell vorgibt. Das TeamRosterControllerkönnte zurückkehren ein RugbyTeamRosterViewoder FootbalTeamRosterView, je nach Art des Teams angefordert.

Es ist im Allgemeinen vorzuziehen, dass Steuerungen zustandslos sind, obwohl ein gewisser Zugriff auf den Status der Benutzersitzung erforderlich oder wünschenswert sein kann. Sie sollten den Zugriff auf diesen Status nach Möglichkeit separat verwalten.

Ich würde wärmstens empfehlen, sich ein tatsächliches MVC-Framework anzusehen, um zu sehen, was es tut und wie es funktioniert. Du musst es nicht benutzen, aber du würdest definitiv ein besseres Verständnis erlangen, bevor du dein eigenes erstellst.

Matthew Flynn
quelle