Model View Controller Pattern / Diskussion
StartSeite | ModelViewControllerPattern/ | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Hallo allerseits!
Ich gebe mir Mühe wiederverwendbaren und leicht wartbaren Code zu schreiben. Und ich gebe zu, dass mir das Programmieren wirklich Spaß macht. Nun möchte ich für ein Projekt das ModelViewControlPattern? verwenden.
Nun ist die Frage ob es eine optimale Implementierung überhaupt gibt. Nun hätte ich gern gewusst, welche Methode Ihr bevorzugt:
- a) Man könnte model und view im control-Objekt instantiieren. Dann wäre das control-Objekt aber nicht gegen ein anderes austauschbar und es scheint nicht so ganz sauber zu sein.
- b) Man könnte ein container-Objekt anlegen, das die Objekte des Patterns instantiiert. Das scheint flexibel und optimal zu sein
- c) ...
Was bevorzugt Ihr denn in Euren Projekten?
-- DanielBrüßler 01.11.04
- Hi Daniel. Ich benutze fast immer das Wiki:FacadePattern im Model, um Zugriffe vom Controler auf das Model zu kapseln. Das Facadeobjekt hat dann alle Aktionen, die im Model zur Verfügung stehen, gegen den Controler gekapselt. Auch evtl. Instanziierungen von Modelobjekten erfolgt, wenn nicht in anderen Modelklassen, dann im Facadeobjekt.
- Ansonsten hilft mir oft daran zu denken, dass der MVC-Code immer so gestrickt sein sollte, dass jederzeit relativ einfach(!) View und Control ausgetauscht werden können. Beispiel: Wenn Du statt einer Weboberfläche mit Struts, Servlets und JSPs eine Swing-GUI aufsetzen möchtest. Um soetwas hinzubekommen darf z.B. keine Businesslogik im Controler vorhanden sein. --BerndSchiffer
- Ja, das ist genau das, was ich mir vorgestellt hab. Nun kann sogar die eigentliche Logik leicht ausgetauscht werden. Das hilft auch während der Entwicklung. Genial.
- Die Fassade ist nur die halbe Miete. So eine Fassade nennt man auch UseCaseController, siehe http://se2c.uni.lu/tiki/se2c-bib_abstract.php?id=554. Eine Anwendung kann einen zentralen UseCaseController haben (gefällt mir persönlich nicht), oder in Komponenten mit eigenen UseCaseControllern? zerfallen. (Diese erzeugen sich dann gegenseitig nach Bedarf.) Die Aktualisierung des Views erfolgt ausschließlich über das BeobachterMuster. Ein UseCaseController weiß nichts von Views, er kann aber durchaus eine Selektion in einer Liste haben.
- Viel gutes habe ich dann noch von der Modellierung in Dolphin Smalltalk gehört. Der Ansatz dort ist eine Weiterentwicklung aus MVC und nennt sich Model-View-Presenter, siehe http://www.object-arts.com/EducationCentre/Overviews/ModelViewPresenter.htm -- SDö
- Sorry, jetzt erst fällt mir auf, dass Daniel auch von einer Nicht-Web-GUI sprechen könnte. Da wäre ein Beobachter und ein Beobachteter evtl. eine gute Idee, während es bei einer Webanwendung wohl nicht die beste Wahl wäre. Um was handelt es sich denn, Daniel? --BerndSchiffer
- Bernd, es ist eine reine Web-Browser-Anwendung. Es handelt sich um ein einfaches Web-CMS, das zwei Typen an content-Elementen kennt. Der controller bekommt seine Parameter von der CGI-Schnittstelle und legt sie im model ab. Im Prinzip ist der Webserver ja der Beobachter. controllerFacade hat die Referenzen von model und view bekommen und enthält außer dem Konstruktor nur die Funktion "actionPerform()". Hier steckt die ganze Steuer-Logik drin, es werden also Aufgaben an model und an view delegiert.
- Die content-Datenstruktur wird komplett im model gehalten und erweitert, und schließlich durch view gerendert.
- Das Schöne am view ist, dass es für sämtliche Fälle die richtigen Bausteine parat hat. Je nach Modus (Besucher/ Redakteur/ Editieren/ Voransicht) fällt die Ausgabe der model-Daten jedesmal verschieden aus. Diese Bausteine sind also nicht über die ganze Anwendung verstreut.
- An einer einzigen Stelle, nämlich im (äußerst schlanken!) controller werden model, view, controllerFacade instantiiert.
- Hab ich das soweit richtig? --DanielBrüßler
- Soweit hört sich das richtig an. Außer das das Prinzip vom Beobachter hier nicht gegeben ist. Der Beobachter informiert den Beobachteten, dass er seinerseits über Updates der Daten des Beobachteten informiert werden möchte. Wenn der Beobachtete neue Daten hat, dann informiert er alle Beobachter (er kennt keinen einzigen Beobachter direkt, sondern nur die abstrakte Klasse oder das Interface Beobachter). Er verteilt keine Informationen direkt an die Beobachter, sondern zeigt nur an, daß die Beobachter nun die Informationen selbst abholen können. Nun untersucht der Beobachter den Beobachteten (Abfragen von Methoden, meist getXXX()).
- Dies ist aber nicht das gleiche Verhalten wie bei MVC. Bei MVC stößt der Controler die Bearbeitung direkt im Model an (per Methode) und wertet dann die Rückgabe aus. Der Controler wird nicht informiert vom Model, sondern wartet einfach auf den Rückgabewert. --bs
- Bei MVC ist der View Beobachter des Modells. Es hält mich aber nichts davon ab, den Controller auch als Beobachter zu implementieren. -- SDö
- Tja, Du schreibst der controller gibt dem model Anweisungen. ACK. Und der Controller muss Rückgaben vom model auswerten - Da bin ich mir nicht sicher, ob wir dasselbe meinen. Damit meinst Du sicher ein allgemeines Feedback TRUE/ FALSE oder eine Referenz zur Weitergabe an das view (beziehungsweise an ein view).
- Das Beobachter-Pattern in Reinkultur in PHP4 umzusetzen wäre Overkill für die Performance. Das mache ich lieber nicht :-)
- Ich denke beim MVC ist freigestellt, wer nun eigentlich wen beobachtet. Bei Web-Applikationen muss man viele Dinge anders lösen, als bei Desktop-Applikationen. Zum einen ist die Laufzeit begrenzt, dann müssen normalerweise alle Objekte pro User-Aktion (klick!) neu instantiiert werden, zum anderen bildet die CGI-Schnittstelle schon einen Teil des Controllers.
- Ich denke, der nächste Schritt für mein Mini-CMS ist, den einen controller so aufzuspalten, dass jeder controller jeweils eine Teilaufgabe erhält.
- --DanielBrüßler
- In welcher Sprache implementierst Du? --BerndSchiffer
- Dieses Projekt in PHP, das hängt mit dem Hosting zusammen. Aber ist das nicht etwas off-topic?
- Naja, mindestens interessant. Du kannst nicht jedes Muster in jeder Sprache gleich gut anwenden, bzw. die unterschiedlichen Sprachen unterstützen von Haus aus einige Pattern besonders gut. --bs
Frage zu TestgetriebeneEntwicklungUndEntwurfsMuster verschoben --DanielBrüßler
Wieso gibt es überhaupt Abhängigkeiten zwischen Controller und View?
FrameworkStruts (Vorreiter von JavaServerFaces) soll MVC vorbildlich umsetzen. In diesem Framework ist der Controler abhängig vom View, da der Controler die Ergebnisse vom Model an das View weiterleitet, ergo das View kennen muss, ergo vom View abhängig ist. --bs
- Eigentlich sollte das Modell selbständig dem View Bescheid über Veränderungen geben (BeobachterMuster). Im Webserver geht das so nicht, vielmehr muss der Controller dem View Bescheid sagen, dass es Zeit ist, eine neue Webseite auszuliefern. Für Web-GUIS gelten also etwas andere Gesetze.
Wenn ich es richtig sehe, musst Du hier grundsätzlich eine enorme Anzahl an Klassen implementieren. Eine einzelne Schaltfläche braucht also ein model, ein view und einen controller?
"Enorme" Anzahl an Objekten, nicht unbedingt an Klassen. Eine einzelne Schaltfläche benötigt tatsächlich Model, View und Controller --- 3 Objekte. Das Model ist nur ein Bit ("gedrückt", man kann sich durchaus weitere Modelle für weitere Eigentschaften vorstellen), der Controller ist der (unsichtbare) Rahmen um den Knopf, der den Mausklick in eine Nachricht an das Model verwandelt und der View ist das sichtbare Rechteck, dass sein Aussehen ändert, wenn der Knopf gedrückt ist.
Das werden deswegen nicht unbedingt mehr Klassen als bei monolithischen Widgets. Rechteckige Rahmen, die Mausklicks verarbeiten, braucht man auch anderswo, ebenso Modelle, die nur ein Bit enthalten. Zudem sind viele kleine Teile etwas Gutes.
Falls ich zu der Irritation beigetragen habe: Der von mir oben erwähnte UseCaseController ist nicht der klassische Controller im MVC-Pattern. Letzterer verarbeitet als Bestandteil der GUI-Schicht Betriebssystem-Events während der UseCaseController als ein Objekt innerhalb der Geschäftslogik anwendungsspezifische Events verarbeitet. -- SDö
Bei Struts im Konkreten und bei WebGUIs? im Allgemeinen ist auch immer die Funktion eines Dispatchers wichtig. Der Dispatcher ist meist eine Klasse, die Nachrichten an einen bestimmten Controler weiterleitet. Sie entscheidet dies aufgrund der bestimmter Parameter im HTTP. Struts als Beispiel kommt mit einem Dispatcher daher, welcher über eine XML-Datei konfiguriert werden kann. In dieser Datei wird das Mapping von Formularen zu Controlern angegeben, sowie, welche Views ein bestimmter Controler ansprechen darf. --bs
- Man kommt ohne einen dedizierten Dispatcher aus, wenn man Controller nach dem CompositePattern? zusammensetzt. So wie eine Box Views gruppiert, gruppiert ein BoxController? Controller. Letztlich muss man das sowieso tun, den Controller einer Listbox will man schon als ganzes behandeln, aber selbstverständlich ist er aus mehreren einfachen Controllern zusammengesetzt. So gesehen hat man am Ende einen einzigen Controller für das gesamte GUI, der freilich die Dispatcherfunktionalität enthält.
Zu "allerdings werden die [im Web-GUI] intern benötigten Objekte nicht zwangsläufig neu erzeugt": In der Ruby-Gemeinschaft ist derzeit die Erzeugung/Verwaltung solcher Objekte über das DependencyInjectionPattern? ein vieldiskutiertes Thema. Es gibt sowohl für das Pattern als auch für Web-Anwendungen im Allgemeinen einige Frameworks. Ursprung der Entwicklung dürfte aber wie so oft aus dem Smalltalk-Lager kommen. Dort wird das Web-Framework Seaside als mögliche Killeranwendung gehandelt. Seaside war Vorbild für mehrere Ruby-Frameworks und es gibt auch (mehr oder weniger erfolgreiche) Versuche soetwas nach Java zu portieren. Links zu den diversen Frameworks siehe InternetProgrammierung. -- SDö
Ich möcht Euch nun mal Danke sagen. Eure Antworten haben mir sehr geholfen das MVC-Pattern zu verstehen und zu nutzen. Was haltet Ihr davon, wenn wir uns das Dispatcher Pattern etwas näher ansehen? Obwohl Bernd für Web-Geschichten ja schon ein sehr gute Beschreibung geschrieben hat: "Der Dispatcher ist meist eine Klasse, die Nachrichten an einen bestimmten Controler weiterleitet. Sie entscheidet dies aufgrund der bestimmter Parameter im HTTP. Struts als Beispiel kommt mit einem Dispatcher daher, welcher über eine XML-Datei konfiguriert werden kann. In dieser Datei wird das Mapping von Formularen zu Controlern angegeben, sowie, welche Views ein bestimmter Controler ansprechen darf". Aber vielleicht lohnt sich doch eine eigene Wiki-Seite? --DanielBrüßler
StartSeite | ModelViewControllerPattern/ | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 12. Februar 2008 13:40 (diff))