Ist das 'C' in MVC wirklich notwendig?

37

Ich verstehe die Rolle des Modells und der Ansicht im Model-View-Controller-Muster, aber es fällt mir schwer zu verstehen, warum ein Controller erforderlich ist.

Nehmen wir an, wir erstellen ein Schachprogramm mit einem MVC-Ansatz. Der Spielstatus sollte das Modell sein, und die GUI sollte die Ansicht sein. Was genau ist der Controller in diesem Fall?

Ist es nur eine separate Klasse, die alle Funktionen enthält, die aufgerufen werden, wenn Sie beispielsweise auf eine Kachel klicken? Warum nicht einfach die gesamte Logik des Modells in der Ansicht selbst ausführen?

Anne Nonimus
quelle
1
Persönlich ist das, was ich tue . Es mag Fälle geben, in denen es keine Alternative zu MVC gibt, aber ich halte es nicht aus.
Mike Dunlavey
10
Drei Wörter ... "Trennung der Sorge".
Travis J
4
Fast alle Windows-Programme vor .net verwendeten Doc-View ohne Controller. Dies scheint relativ erfolgreich gewesen zu sein.
Martin Beckett
Martin, unfähige Monoliten.
Unabhängige
Ich habe unten geantwortet, aber ich füge hinzu, dass Sie eine Anwendung ohne bestimmte Controller-Klassen erstellen können, aber das wäre nicht MVC. Sie gehen von einem "MVC-Ansatz" aus, also spielen Controller eine wichtige Rolle. Wenn Sie ein Paradigma wählen, das nicht MVC ist, ist es durchaus möglich, dass Sie keine Controller haben.
Caleb

Antworten:

4

Anhand Ihres Beispiels würde der Controller entscheiden, was ein legaler Schachzug ist oder nicht. Der Controller würde die Ansicht wissen lassen, wie die Teile beim Start auf der Platine angeordnet werden sollen, wobei die vom Modell erhaltenen Informationen verwendet werden. Es gibt weitere Dinge, die der Controller erledigen kann, aber der Schlüssel ist, über Business Logic auf dieser Ebene nachzudenken.

Es gibt Zeiten, in denen der Controller lediglich Informationen wie eine Anmeldeseite hin und her weitergibt. In anderen Fällen ist der Controller der schwierige Teil der Entwicklung, da auf dieser Ebene viele Dinge zu erledigen sind, z. B. das Durchsetzen von Regeln oder das Ausführen komplizierter Berechnungen. Vergiss den Controller nicht!

JustinDoesWork
quelle
36
"Mit Ihrem Beispiel würde der Controller entscheiden, was ein legaler Schachzug ist oder nicht." Dies ist ein schlechtes Beispiel :( Eine solche Logik soll auch im Modell vorhanden sein. Andernfalls wird Ihre Logik zwischen dem Controller und dem Modell aufgeteilt.
Dime
6
@Dime - Das Modell sollte keinerlei Logik enthalten. Der Controller wird die einzige Haltelogik sein, daher "Steuern".
Travis J
34
@ TravisJ Da stimme ich nicht ganz zu. Controlling bedeutet nicht, zu wissen, wie man einen Job macht. Es geht darum, die Objekte zu steuern, die dies tun. Daher würde die Logik für die Ausführung der Arbeit im Modell liegen und der Controller würde steuern, welches Modell verwendet werden soll, um die erforderlichen Anforderungen der Aktion usw. auszuführen. Zu viel Logik in Controllern wäre aus meiner Sicht ein Rezept für Controller-Blot ...
dreza
25
Der Sinn von OOP ist es, zusammenhängende Daten und Verhaltensweisen zusammenzuhalten und intern zu verkapseln. "Modell" modelliert sowohl Verhalten als auch Daten.
Misko
12
-1 Der Controller darf keine Geschäftslogik enthalten. Das Modell ist "die App", es enthält die Daten und verfügt über aufrufbare Routinen für alles, was in der App passieren kann . nicht unbedingt alle in einer Datei oder Klasse. Die Ansicht visualisiert den Zustand des Modells. Der Controller verbindet das Modell / die Ansicht und die reale Welt / Eingabe. Möchten Sie die App als Web-App "veröffentlichen" ? Benötigen Sie nur einen Controller, der HTTP und eine entsprechende HTML-basierte Ansicht verarbeitet. Möchten Sie eine Befehlszeilenschnittstelle für Ihre App? Benötigen Sie nur eine entsprechende Steuerung und Ansicht. Das Modell, die Geschäftslogik, ändert sich in diesen Fällen nie.
Deceze
39

Warum nicht einfach die gesamte Logik des Modells in der Ansicht selbst ausführen?

Der Controller ist der Klebstoff, der das Modell und die Ansicht miteinander verbindet, und es ist auch die Isolierung, die sie voneinander trennt. Das Modell sollte nichts über die Ansicht wissen und umgekehrt (zumindest in Apples Version von MVC). Der Controller verhält sich wie ein Zweiwegeadapter, der Benutzeraktionen aus der Ansicht in Nachrichten an das Modell übersetzt und die Ansicht mit Daten aus dem Modell konfiguriert.

Durch die Verwendung des Controllers zur Trennung von Modell und Ansicht wird der Code wiederverwendbarer, testbarer und flexibler. Betrachten Sie Ihr Schachbeispiel. Das Modell würde natürlich den Spielstatus enthalten, aber es könnte auch die Logik enthalten, die Änderungen des Spielstatus beeinflusst, z. B. das Bestimmen, ob ein Zug zulässig ist, und das Entscheiden, wann das Spiel beendet ist. Die Ansicht zeigt ein Schachbrett und Figuren an und sendet Nachrichten, wenn sich eine Figur bewegt, aber sie weiß nichts über die Bedeutung hinter den Figuren, wie sich jede Figur bewegt usw. Der Controller weiß sowohl über das Modell als auch über die Ansicht Bescheid der Gesamtablauf des Programms. Wenn der Benutzer auf die Schaltfläche "Neues Spiel" klickt, weist ein Controller das Modell an, ein Spiel zu erstellen, und verwendet den Status des neuen Spiels, um das Spielbrett einzurichten. Wenn der Benutzer einen Zug macht,

Sehen Sie sich an, was Sie erhalten, wenn Sie das Modell und die Ansicht getrennt halten:

  • Sie können das Modell oder die Ansicht ändern, ohne die andere zu ändern. Möglicherweise müssen Sie den Controller aktualisieren, wenn Sie einen der beiden ändern. Dies ist jedoch Teil des Vorteils: Die Teile des Programms, die sich am wahrscheinlichsten ändern, sind im Controller konzentriert.

  • Modell und Ansicht können wiederverwendet werden. Beispielsweise könnten Sie dieselbe Schachbrettansicht mit einem RSS-Feed als Modell verwenden, um berühmte Spiele zu veranschaulichen. Sie können auch dasselbe Modell verwenden und die Ansicht durch eine webbasierte Oberfläche ersetzen.

  • Es ist einfach, Tests sowohl für das Modell als auch für die Ansicht zu schreiben, um sicherzustellen, dass sie ordnungsgemäß funktionieren.

  • Sowohl das Modell als auch die Ansicht können häufig die Vorteile von Standardteilen nutzen: Arrays, Karten, Mengen, Zeichenfolgen und andere Datencontainer für das Modell; Schaltflächen, Steuerelemente, Textfelder, Bildansichten, Tabellen und andere Elemente für die Ansicht.

Caleb
quelle
1
In der ursprünglichen MVC-Architektur für Desktopanwendungen waren Ansichten aktive Klassen, die das Modell direkt beobachteten und von der Steuerung getrennt waren.
Kevin Cline
Das Problem bei allen Antworten ist, dass es so viele Interpretationen von MVC gibt, wie Leute posten. Die oben aufgeführten Vorteile gelten nur für eine bestimmte Interpretation von MVC. Wenn man den größten Teil der Logik in den Controller (oder das Modell) einbinden und den View-Aufruf / die Initiierung bestimmter Methodenaufrufe auf dem Controller durchführen möchte, ist die Controller / Model-Kombination eigenständig und sehr wiederverwendbar. Meistens wird eine neue Sichtweise benötigt. Ich hatte nie das Bedürfnis, eine Ansicht wiederzuverwenden. Sogar Ihr RSS-Beispiel kann problemlos mit einer neuen Ansicht bearbeitet werden, in der Ihre alte Ansicht mit einer dazwischen liegenden RSS-Ebene verwendet wird.
Dunk
2
@Dunk: Es ist wichtig, die Geschäftslogik von der Benutzeroberfläche zu trennen, damit die Geschäftslogik direkt getestet werden kann.
Kevin Cline
@ Kevin: Ich stimme vollkommen zu, Geschäftslogik gehört nicht in die Benutzeroberfläche. Der Controller muss jedoch nicht Teil der Benutzeroberfläche sein. Das meine ich damit, dass es viele Definitionen gibt. In der Definition einer Person handhabt der Controller das Drücken von Tasten, während eine andere Person dies als Teil der Ansicht einfügt. Wenn die Ansicht weiß, wie Bedieneraktionen (z. B. Tastendrücke / Elementauswahl) in Anwendungsanforderungen umgewandelt werden, kann der Controller / das Modell mit nahezu jeder Art von Benutzeroberfläche, einschließlich GUI-, Konsolen- oder Netzwerkschnittstellen, wieder verwendet werden.
Dunk
1
@Dunk: Ich nehme an, Sie können alles, was Sie möchten, als "Controller" bezeichnen, aber in der MVC-Architektur ist der Controller von der Benutzeroberfläche abhängig und daher Teil dieser.
Kevin Cline
7

Es gibt viele, viele verschiedene Möglichkeiten, dieses allgemeine Entwurfsmuster zu implementieren, aber die Grundidee besteht darin, die verschiedenen Belange nach Bedarf zu trennen. MVC ist eine nette Abstraktion in dem Sinne, dass:

Modell : Stellt die Daten dar, was auch immer dies bedeuten mag.
Ansicht : Stellt die Benutzeroberfläche dar, was auch immer dies bedeuten mag.
Steuerung : Stellt den Klebstoff dar, der bewirkt, dass das Modell und die Ansicht interagieren, was auch immer dies bedeuten mag

Es ist extrem flexibel, weil es nicht viel spezifiziert. Viele Leute verschwenden viel Bandbreite und diskutieren, was jedes Element bedeuten könnte, welche Namen stattdessen verwendet werden sollten und ob es wirklich 3 oder 2 oder 4 oder 5 Komponenten geben sollte gewisser Grad.

Die Idee ist, die verschiedenen "Brocken" der Logik zu trennen, damit sie sich nicht überlappen. Halten Sie Ihre Präsentationen zusammen, halten Sie Ihre Daten zusammen, halten Sie Ihre Logik zusammen, halten Sie Ihre Kommunikation zusammen. Und so weiter. In gewissem Maße ist es umso einfacher, interessante Dinge mit ihnen zu tun, je weniger sich diese Problembereiche überschneiden.

Das ist alles, worüber Sie sich wirklich Sorgen machen sollten.

tylerl
quelle
3
Leim, Leim, ich mag diese Definition, sie ist so richtig: Das ganze Modell sollte MVG heißen und die Leute würden aufhören, sich auf der Suche nach Eleganz am Kopf zu kratzen, wo es nichts zu finden gibt.
ZJR
1
+1 für "Kleber"; Dies bedeutet auch, dass dies der Teil ist, der am besten für die Ausführung in einer Skriptsprache geeignet ist (da diese sich beim Kleben in der Regel auszeichnen).
Donal Fellows
@DonalFellows Ich mag diesen Gedanken sehr. Etwas, das zwei unterschiedliche Entitäten "zusammenklebt", erfordert viel Flexibilität, die schwach typisierte Skriptsprachen (z. B. JavaScript) fördern
Zack Macomber
4

Alles gute Antworten soweit. Meine zwei Cent sind, dass ich den Controller gerne als hauptsächlich aus Fragen wie Was und Wo aufgebaut betrachte.

  • Ich wurde gefragt, ob eine Schachfigur (Ansicht) nach x verschoben werden kann. Ist es
    erlaubt Ich bin nicht sicher, aber ich weiß, wo und wen ich fragen soll (das Modell).
  • Etwas hat mich gebeten, meine Daten zu speichern. Wie zum Teufel mache ich das? Ich weiß allerdings, wo ich fragen muss! Wie wir die Daten speichern oder wo sie gespeichert werden, weiß ich nicht, aber diese Repository-Klasse sollte es wissen. Ich leite es weiter und lasse es damit umgehen.
  • Ich muss dem Benutzer die aktuelle Schachfigurposition anzeigen, in die das Modell sie verschoben hat. Sind Sie sich nicht sicher, ob ich das Stück grün oder gelb zeigen möchte? Bah, wen kümmert es, ich weiß, dass es eine Ansicht gibt, die damit umgehen kann, also gebe ich die Daten weiter und sie können entscheiden, wie sie angezeigt werden.

Diese kleinen Schnipsel sind Beispiele dafür, wie ich mich an die Abstraktion und das Konzept zu erinnern versuche, die MVC zu vermitteln versucht. Was, wo und wie sind meine drei Hauptgedankenprozesse.

Was und wo => Controller Wie und wann => Modelle und Ansichten

Im Wesentlichen sind meine Controller-Aktionen in der Regel klein und kompakt und sehen beim Lesen manchmal wie Zeitverschwendung aus. Bei näherer Betrachtung agieren sie als Verkehrssignalgeber, leiten die verschiedenen Anfragen an die zuständigen Mitarbeiter weiter, erledigen jedoch keine der eigentlichen Arbeiten selbst.

dreza
quelle
2

Ein Controller kann dabei helfen, die Schnittstellen sowohl der Ansicht als auch des Modells zu abstrahieren, damit sie sich nicht direkt kennen müssen. Je weniger ein Objekt wissen muss, desto tragbarer und prüfbarer wird es.

Zum Beispiel könnte das Model eine andere Instanz von sich selbst über einen Controller abspielen. Oder ein vernetzter Controller könnte die Views-Objekte von zwei Spielern miteinander verbinden. Oder es könnte ein Turing-Test sein, bei dem niemand weiß, welcher.

hotpaw2
quelle
2

Wenn Sie sich mit Ereignishandlern beschäftigen, kommt dies wirklich ins Spiel, aber Sie benötigen immer noch den Controller, um die Interaktionen zwischen der Ansicht und dem Modell zu handhaben. Idealerweise soll die Ansicht nichts über das Modell wissen. Denken Sie darüber nach, möchten Sie, dass ein JSP alle Datenbankaufrufe direkt durchführt? (Es sei denn, es handelt sich um eine Anmeldesuche.) Sie möchten, dass die Ansicht Daten rendert und keine Geschäftslogik enthält, es sei denn, es handelt sich um eine Ansichtsrenderlogik, die Geschäftslogik wird jedoch nicht beibehalten.

In GWT erhalten Sie mit MVP eine sauberere Trennung. In der Ansicht befindet sich überhaupt keine Geschäftslogik (wenn sie richtig ausgeführt wird). Der Präsentator fungiert als Controller und die Ansicht kennt das Modell nicht. Modelldaten werden einfach an die Ansicht übergeben.


quelle
1

Die Dokumentansicht (dh die Modellansicht) ist das Standardmodell für die meisten in MFC geschriebenen Windows-Apps, sodass sie in vielen Fällen funktionieren muss.

Martin Beckett
quelle
1

Ich verstehe die Rolle des Modells und der Ansicht im Model-View-Controller-Muster, aber es fällt mir schwer zu verstehen, warum ein Controller erforderlich ist.

Sind Sie sich da sicher? (Zumindest wie ursprünglich beschrieben) Der Sinn des Modells ist es, das Domain-Modell zu sein. Die Ansicht soll dem Benutzer das Domain-Modell anzeigen. Der Controller soll den Low-Level-Eingang auf das High-Level-Modell abbilden. Soweit ich das beurteilen kann, handelt es sich um Folgendes: A) eine hohe Nutzung der SRP. B) Das Modell wurde als wichtiger Teil der App angesehen. Halten Sie daher unwichtige und schnell wechselnde Elemente von der App fern. C) leicht testbare (und skriptfähige) Geschäftslogik.

Stellen Sie sich vor, Sie möchten Ihr Schachprogramm für Blinde nutzbar machen, und tauschen die Ansicht gegen eine hörbare Version und eine Steuerung aus, die mit der Tastatur funktioniert. Angenommen, Sie möchten Spiele per E-Mail hinzufügen, fügen Sie einen Controller hinzu, der Text akzeptiert. Nettoversion des Spiels? Ein Controller, der Befehle von einem Socket akzeptiert, würde diese Aufgabe übernehmen. Fügen Sie eine schöne 3D-Darstellung hinzu, eine coole neue Ansicht. Keine Modelländerungen notwendig Schach ist immer noch Schach.

Wenn Sie Eingaben mit der Modelldarstellung mischen, verlieren Sie diese Fähigkeit. Plötzlich ist Schach nicht mehr Schach, sondern Schach mit einer Maus, die sich von Schach mit Tastatur oder Netzwerkverbindung unterscheidet.

Steinmetalle
quelle
0

Ich denke, MVC ist dumm, vielleicht funktioniert es in bestimmten Bereichen gut, aber persönlich sind selbst von mir geschriebene Websites nicht für MVC geeignet. Theres ein Grund, warum Sie Frontend, Backend und nie Datenbank-Ende oder etwas anderes Ende hören

IMO sollte es eine API (Backend) und die App geben, die die API (Frontend) verwendet. Ich denke, Sie könnten die GET-Anfrage den Controller (der einfach die Backend-API aufruft) und die HTML-Ansicht aufrufen, aber ich höre normalerweise keine Leute, die über die Ansicht als reine HTML- oder Modell-Backend-API sprechen.

IMO alles sollte eine solide API sein. Eigentlich müssen sie nicht solide sein (wie in sauber und gut gebaut), aber ihre Interna sollten privat bleiben und die App / Frontend / außerhalb der API sollte niemals die Datenbankverbindung sagen oder in der Lage sein, unformatierte Abfragen zu machen.

Nun, wenn Ihr Code / Design Kleber beinhaltet, ist es in Ordnung. Wenn es in Ihrem Schachspiel einige Markups gibt, die Sie bearbeiten können, um die Benutzeroberfläche zu gestalten, sammelt die Benutzeroberfläche die Koordinaten / Eingaben und ruft MovePiece (srcPosition, dstPostion) auf (dies kann einen Bool oder eine Aufzählung zurückgeben, um zu sagen, ob es sich um einen gültigen Zug handelt oder nicht ) und dein OK, wenn alle Logik im Modell ist, dann nenne es sicher MVC. Allerdings würde ich die Dinge immer noch nach Klassen und APIs organisieren und sicherstellen, dass es keine Kitchen-Sink-Klasse gibt, die alles berührt (noch APIs, die über alles Bescheid wissen müssen).


quelle
Ihre Meinung ist uns willkommen, aber diese Antwort versucht nicht, die Frage des OP zu beantworten.
Caleb
0

Stellen Sie sich einen Browser vor, der eine statische Webseite anzeigt. Das Modell ist das HTML. Die Ansicht ist das tatsächliche Ergebnis auf dem Bildschirm.

Fügen Sie nun etwas JavaScript hinzu. Das ist der Controller. Wenn der Benutzer auf eine Schaltfläche klickt oder etwas zieht, das das Ereignis an das JavaScript sendet, entscheidet er, was zu tun ist, und ändert das zugrunde liegende HTML (Modell). Der Browser / Renderer zeigt diese Änderungen auf dem Bildschirm an (Ansicht).

Möglicherweise wird auf eine andere Schaltfläche geklickt, das Ereignis wird an einen Handler (Controller) gesendet, und es kann dazu führen, dass weitere Daten an einen Webservice gesendet werden. Das Ergebnis wird dann zum HTML (Modell) hinzugefügt.

Der Controller reagiert auf Ereignisse und steuert, was sich im Modell und damit auf dem Bildschirm / in der Ansicht befindet.

Wenn Sie etwas zurücktreten, können Sie sich den gesamten Browser als Ansicht und den Server als Controller und die Daten als Modell vorstellen. Wenn der Benutzer auf eine Schaltfläche im Browser klickt, sammelt er Ressourcen als HTML-Seite (Modell) und sendet diese an den Browser, um sie anzuzeigen (Ansicht).

Im Server empfängt der 'Code' (Controller) unabhängig davon, ob es sich um asp, php oder java handelt, das Ereignis click und fragt eine Datenbank oder ein Dokumentrepository (Model) ab und erstellt HTML. Aus Sicht des Servers ist das Ergebnis aller Aktionen eine Ansicht (HTML) des zugrunde liegenden Datenspeichers (Modells). Aus Client-Sicht ist das Ergebnis der Anforderung an den Server jedoch das Modell (HTML).

Auch wenn Sie Ihr JavaScript in Ihrem HTML-Code oder Ihr PHP-Code in Ihrem HTML-Code durcheinander bringen, ist das Modell, die Ansicht und der Controller immer noch vorhanden. Auch wenn Sie sich Ihre Anfrage an einen Server und die Antwort vom Server als eine einfache Einbahnstraße vorstellen, gibt es immer noch ein Modell, eine Ansicht und einen Controller.

Zeus
quelle
-2

Meiner Erfahrung nach wird der Controller in einem herkömmlichen Desktop-MVC-GUI-Programm in die Ansicht eingeblendet. Die meisten Leute nehmen sich nicht die Zeit, eine Controller-Klasse herauszufiltern.

das vierköpfige buch sagt:

Entwurfsmuster in Smalltalk MVC

Die MVC-Triade (Model / View / Controller) der Klassen [KP88] wird zum Erstellen von Benutzeroberflächen in Smalltalk-80 verwendet. Wenn Sie sich die Entwurfsmuster in MVC ansehen, können Sie erkennen, was wir unter dem Begriff "Muster" verstehen.

MVC besteht aus drei Arten von Objekten. Das Modell ist das Anwendungsobjekt, die Ansicht die Bildschirmdarstellung und der Controller definiert, wie die Benutzeroberfläche auf Benutzereingaben reagiert. Vor MVC neigten Benutzeroberflächendesigns dazu, diese Objekte zusammenzufassen. MVC entkoppelt sie, um die Flexibilität und Wiederverwendung zu erhöhen.

MVC entkoppelt Ansichten und Modelle, indem ein Abonnement- / Benachrichtigungsprotokoll zwischen ihnen erstellt wird. Eine Ansicht muss sicherstellen, dass ihr Erscheinungsbild den Status des Modells widerspiegelt. Wann immer sich die Daten des Modells ändern, benachrichtigt das Modell die Ansichten, die davon abhängen. Als Antwort erhält jede Ansicht die Möglichkeit, sich selbst zu aktualisieren. Mit diesem Ansatz können Sie einem Modell mehrere Ansichten hinzufügen, um unterschiedliche Präsentationen bereitzustellen. Sie können auch neue Ansichten für ein Modell erstellen, ohne es neu zu schreiben.

Das folgende Diagramm zeigt ein Modell und drei Ansichten. (Wir haben die Controller der Einfachheit halber weggelassen.) Das Modell enthält einige Datenwerte, und die Ansichten, die eine Tabelle, ein Histogramm und ein Kreisdiagramm definieren, zeigen diese Daten auf verschiedene Arten an. Das Modell kommuniziert mit seinen Ansichten, wenn sich seine Werte ändern, und die Ansichten kommunizieren mit dem Modell, um auf diese Werte zuzugreifen.

Ausgehend vom Nennwert spiegelt dieses Beispiel ein Design wider, das Ansichten von Modellen entkoppelt. Der Entwurf ist jedoch auf ein allgemeineres Problem anwendbar: Das Entkoppeln von Objekten, sodass Änderungen an einem eine beliebige Anzahl von anderen beeinflussen können, ohne dass das geänderte Objekt Details der anderen kennen muss. Dieser allgemeinere Entwurf wird durch das Entwurfsmuster Observer (Seite 329) beschrieben.

Ein weiteres Merkmal von MVC ist, dass Ansichten verschachtelt werden können. Beispielsweise kann ein Bedienfeld mit Schaltflächen als komplexe Ansicht mit verschachtelten Schaltflächenansichten implementiert werden. Die Benutzeroberfläche für einen Objektinspektor kann aus verschachtelten Ansichten bestehen, die in einem Debugger wiederverwendet werden können. MVC unterstützt verschachtelte Ansichten mit der CompositeView-Klasse, einer Unterklasse von View. CompositeView-Objekte verhalten sich wie View-Objekte. Eine zusammengesetzte Ansicht kann überall dort verwendet werden, wo eine Ansicht verwendet werden kann. Sie enthält und verwaltet jedoch auch verschachtelte Ansichten.

Auch hier können wir uns ein Design vorstellen, mit dem wir eine zusammengesetzte Ansicht genauso behandeln können, wie wir eine ihrer Komponenten behandeln. Der Entwurf ist jedoch auf ein allgemeineres Problem anwendbar, das auftritt, wenn Objekte gruppiert und die Gruppe wie ein einzelnes Objekt behandelt werden sollen. Dieser allgemeinere Entwurf wird durch das Entwurfsmuster Composite (163) beschrieben. Hiermit können Sie eine Klassenhierarchie erstellen, in der einige Unterklassen primitive Objekte (z. B. Button) und andere Klassen zusammengesetzte Objekte (CompositeView) definieren, die die Primitive zu komplexeren Objekten zusammensetzen.

Mit MVC können Sie auch die Art und Weise ändern, in der eine Ansicht auf Benutzereingaben reagiert, ohne die visuelle Darstellung zu ändern. Sie können beispielsweise die Art und Weise ändern, in der die Tastatur darauf reagiert, oder ein Popup-Menü anstelle von Befehlstasten verwenden. MVC kapselt den Antwortmechanismus in ein Controller-Objekt. Es gibt eine Klassenhierarchie von Controllern, die es einfach macht, einen neuen Controller als Variation eines vorhandenen Controllers zu erstellen.

Eine Ansicht verwendet eine Instanz einer Controller-Unterklasse, um eine bestimmte Antwortstrategie zu implementieren. Um eine andere Strategie zu implementieren, ersetzen Sie einfach die Instanz durch eine andere Art von Controller. Es ist sogar möglich, den Controller einer Ansicht zur Laufzeit zu ändern, damit die Ansicht die Art und Weise ändert, in der sie auf Benutzereingaben reagiert. Beispielsweise kann eine Ansicht deaktiviert werden, damit sie keine Eingaben akzeptiert, indem ihr ein Controller zugewiesen wird, der Eingabeereignisse ignoriert.

Die View-Controller-Beziehung ist ein Beispiel für das Entwurfsmuster Strategy (315). Eine Strategie ist ein Objekt, das einen Algorithmus darstellt. Dies ist nützlich, wenn Sie den Algorithmus entweder statisch oder dynamisch ersetzen möchten, wenn Sie viele Varianten des Algorithmus haben oder wenn der Algorithmus komplexe Datenstrukturen aufweist, die Sie kapseln möchten.

MVC verwendet andere Entwurfsmuster, z. B. die Factory-Methode (107), um die Standard-Controller-Klasse für eine Ansicht anzugeben, und Decorator (175), um einer Ansicht einen Bildlauf hinzuzufügen. Die Hauptbeziehungen in MVC sind jedoch durch die Entwurfsmuster Observer, Composite und Strategy gegeben.

Ray Tayek
quelle
1
Es sieht so aus, als ob dieser gesamte Beitrag abzüglich der ersten beiden Absätze wörtlich aus Design Patterns übernommen wurde . Ich habe diesen Abschnitt als Zitat formatiert, damit die Leser das verstehen - bitte bearbeiten Sie ihn, wenn ich eigene Absätze zitiert habe.
Caleb
1
Ich muss Ihrer Meinung nicht zustimmen, dass "der Controller in die Sicht geraten ist". Vielleicht hängt es von der Plattform und dem Framework ab, das Sie verwenden, aber in der Cocoa- und Cocoa Touch-Programmierung ist es weitaus üblicher, geeignete Controller zu erstellen, als sie wegzulassen. Wenn ein Objective-C-Programmierer eine der Kategorien auslässt, ist es fast sicher, dass das Modell darunter leidet.
Caleb
Wenn Sie zustimmen, dass dies die "richtige" Interpretation von MVC ist, kauft MVC absolut nichts. Es kann auch nur MV sein und das C weglassen, da Sie jedes Mal, wenn Sie eine neue Ansicht erstellen, auch einen neuen Controller erstellen müssen. Was nützt es also, wenn man sich die Mühe macht, sie zu trennen, und nicht aus theoretischen Gründen, um die Bedenken zu trennen?
Dunk