Die Hauptidee hinter OOP ist die Vereinheitlichung von Daten und Verhalten in einer einzigen Entität - dem Objekt. Bei der prozeduralen Programmierung gibt es Daten und separate Algorithmen, die die Daten modifizieren.
In dem Model-View-Controller-Muster sind die Daten und die Logik / Algorithmen in unterschiedlichen Einheiten, dem Modell bzw. dem Controller, angeordnet. Sollte in einem äquivalenten OOP-Ansatz das Modell und der Controller nicht in derselben logischen Entität platziert werden?
design
object-oriented
mvc
m3th0dman
quelle
quelle
Antworten:
MVC ist eine Übung in Separation of Concerns , einer UI-Architektur. Dies ist eine Möglichkeit, die Komplexität zu korrigieren, die in Benutzeroberflächen auftreten kann, wenn die Präsentation nicht vom Inhalt getrennt wird .
Theoretisch können alle Objekte ein Verhalten aufweisen, das auf den Daten beruht, die sie enthalten, und dass Daten und Verhalten eingekapselt bleiben . In der Praxis kann ein bestimmtes OOP-Objekt eine Logik aufweisen, die seinen Daten entspricht, oder es kann überhaupt keine Logik aufweisen (beispielsweise ein Datenübertragungsobjekt ).
In MVC geht die Geschäftslogik in das Modell und nicht in den Controller. Der Controller ist wirklich nur ein Vermittler, um die Ansicht und das Modell miteinander zu verbinden. Im Modell können Sie also Daten und Verhalten an derselben Stelle haben.
Aber selbst diese Anordnung garantiert keine strikte Daten- / Verhaltensfusion. Objekte, die nur Daten enthalten, können von anderen Klassen bearbeitet werden, die nur Logik enthalten. Dies ist eine durchaus akzeptable Verwendung von OOP.
Ich gebe Ihnen ein konkretes Beispiel. Dies ist ein bisschen erfunden, aber nehmen wir an, Sie haben ein
Currency
Objekt, und dieses Objekt kann sich in jeder verfügbaren Währung darstellen, die an den Dollar gebunden ist. Sie hätten also Methoden wie:... und dieses Verhalten würde mit dem Currency-Objekt gekapselt.
Aber was ist, wenn ich die Währung von einem Konto auf ein anderes übertragen oder eine Währung einzahlen möchte? Würde dieses Verhalten auch im Currency-Objekt enthalten sein? Nein, würde es nicht. Das Geld in Ihrer Brieftasche kann nicht von Ihrer Brieftasche auf Ihr Bankkonto überwiesen werden. Sie benötigen einen oder mehrere Agenten (einen Kassierer oder Geldautomaten), um dieses Geld auf Ihr Konto zu bekommen.
Dieses Verhalten würde also in ein
Teller
Objekt eingekapseltCurrency
undAccount
Objekte als Eingaben akzeptieren , es würde jedoch keine Daten selbst enthalten, außer möglicherweise ein wenig lokalen Status (oder möglicherweise einTransaction
Objekt), um die Verarbeitung der Eingabeobjekte zu unterstützen.quelle
Teller
platziert werden? In dem,Controller
von wo aus dieTeller's
Methoden aufgerufen werden oder in dem,Model
weil es Teil der Geschäftslogik ist?Teller
geht in dieModel
, obwohl es vom controller aufgerufen werden könnte. Es ist Teil der Geschäftsdomäne.MVC arbeitet auf einer viel höheren Abstraktionsebene als einzelne Objekte. Tatsächlich besteht jedes der drei Objekte (Modell, Ansicht und Controller) in der Regel aus vielen Objekten, die sowohl Daten als auch Verhalten aufweisen.
Dass Objekte, die Daten und Verhalten einschließen, ein guter grundlegender Baustein für Programme im Allgemeinen sind, bedeutet nicht, dass es das beste Muster auf allen Abstraktionsebenen und für alle Zwecke ist.
quelle
OOP schränkt die Interaktionen zwischen Objekten, die jeweils eigene Daten und ein eigenes Verhalten aufweisen, nicht ein.
Denken Sie an eine Ameisen- und eine Ameisenkolonie-Analogie: Das Verhalten einer einzelnen Ameise (den ganzen Tag herumlaufen, Nahrung bringen) unterscheidet sich vom Verhalten der gesamten Kolonie (den begehrtesten Ort finden, mehr Ameisen bilden). Das MVC-Muster beschreibt die gewünschte soziale Struktur einer Ameisenkolonie, während OOP das Design einzelner Ameisen steuert.
quelle
Bei OOP geht es auch um die Trennung von Belangen , dh die Trennung verschiedener Rollen / Verantwortlichkeiten in verschiedenen Objekten.
MVC unterteilt sich in folgende Komponenten:
Diese Zuständigkeiten sind also klar voneinander getrennt und sollten in der Tat in mehrere Einheiten aufgeteilt werden.
quelle
Modell und Controller sind zwei unterschiedliche Rollen. Ein Modell hat sowohl Status als auch Logik, und ein Controller hat sowohl Status als auch Logik. Die Tatsache, dass sie kommunizieren, unterbricht weder die Kapselung einer der beiden - der Controller weiß oder kümmert sich nicht darum, wie das Modell seine Daten speichert oder was er mit den Daten macht, wenn der Controller einen Teil davon abruft oder aktualisiert. Das Modell weiß oder kümmert sich nicht darum, was der Controller mit den vom Modell bereitgestellten Daten macht.
Stellen Sie sich das so vor: Wenn Objekte Daten nicht ohne Unterbrechung der Kapselung hin und her übertragen könnten, könnten Sie wirklich nur ein Objekt haben!
MVC ist ein OOP-Ansatz - insbesondere ein Rezept für die Entscheidung, wie Objekte zum effektiven Organisieren eines Programms verwendet werden sollen. Und nein , das Modell und der Controller sollten nicht dieselbe Entität sein. Ein Controller ermöglicht die Trennung zwischen Modell und Ansicht. Durch die Unabhängigkeit von Modell und Ansicht sind sie sowohl testbarer als auch wiederverwendbarer.
quelle
MVC ist ein Muster, das eine sinnvolle Art der Interaktion von Objekten beschreibt. es ist selbst keine Meta-Klasse. Dabei geht es bei OO darum, Verhaltensweisen und Daten von Entitäten zu beschreiben und wie diese Entitäten interagieren. Es geht nicht darum, das gesamte System zu einem massiven Objekt zu vereinen.
quelle
Controller repräsentiert nicht das Verhalten eines Modells. Controller repräsentieren insgesamt das Verhalten der gesamten Anwendung - was ein Benutzer tun und was ein Benutzer sehen kann.
Es ist falsch, Controller und Modelle als eine Einheit anzusehen. Sie haben unterschiedliche Zwecke, unterschiedliche Semantiken und sollten daher nicht in einem Objekt vereint werden.
quelle
Die Modellschicht besteht nicht nur aus Daten, sondern die Controllerschicht ist nur aus Logik.
Die Controller-Ebene verfügt für ihre Zwecke über eine vollständige Sammlung von Objekten. Es gibt Objekte zum Empfangen von Eingaben aus der Ansicht und zum Umwandeln dieser Eingaben in eine Form, die das Modell verarbeiten kann. Das Struts Java-Framework hat ein gutes Beispiel dafür in seinem Aktions- / Formularmodell. Das Formular wird mit Eingaben des Benutzers ausgefüllt und dann an die Aktion übergeben. Die Aktion verwendet diese Daten, um das Modell zu bearbeiten.
Ebenso besteht der Model-Layer nicht nur aus Daten. Nehmen Sie zum Beispiel ein Benutzerobjekt - Sie benötigen möglicherweise Code, der einen Benutzer aus einer Datenbank abruft, oder Code, um einen Benutzer mit einem Auftrag zu verknüpfen oder um zu überprüfen, ob die Adresse des Benutzers in dem Bereich liegt, in dem sich die Dienste Ihres Unternehmens befinden Bild. Dies ist keine Steuerungslogik. Es ist eine Geschäftslogik, die viele dazu veranlasst, ihre Modellebene in mehrere Ebenen zu unterteilen, z. B. Service- oder Manager-Ebenen für die Geschäftslogik, eine DAO-Ebene (Database Access Object) für den Datenbankzugriff und andere.
MVC ist keine Methode zum Organisieren einzelner Modelloperationen. Es funktioniert auf einer höheren Ebene - es ist eine Methode zum Organisieren, wie auf die Anwendung zugegriffen wird. Die Ansicht dient zum Darstellen von Daten und menschlichen Handlungen zum Manipulieren, der Controller zum Übersetzen zwischen Benutzeraktionen und den verschiedenen Ansichten, und im Modell befinden sich Geschäftsdaten und die Geschäftsgründe dafür.
quelle
Bei OOP geht es darum, Daten und Funktionen , die zusammengehören, zu gruppieren . Eine Berechnung, die auf bestimmten Daten basiert, gehört nicht immer zu diesen Daten.
In MVC wird die Funktionalität zum Anzeigen eines Datenelements (Ansicht) von den Daten (Modell) getrennt gehalten. Warum ist das so? Dies ist speziell so, dass die Anzeigelogik geändert werden kann, ohne dass die zugrunde liegenden Daten geändert werden müssen. Dies erleichtert das Ändern der Ansicht, wenn Sie die gleichen Daten anders darstellen müssen: oder wenn sich die Eigenschaften der Anzeigehardware ändern: oder wenn Sie von Windows zu Linux wechseln. oder wenn Sie möchten, dass zwei Personen die gleichen Daten auf zwei verschiedene Arten betrachten.
MVC steht nicht in Konflikt mit OOP - es wird tatsächlich von einer korrekten Anwendung objektorientierter Prinzipien abgeleitet.
quelle
Ich glaube, Sie verwechseln persistente Daten, die an ein Modellobjekt gebunden sind, mit den Anwendungsdaten aus den Datenbanken, mit denen das Modell interagiert. Ein Modell enthält Geschäftslogik und Regeln für die Arbeit mit Datenbanken und die Durchführung von Transaktionen. Es kann interne Statusflags setzen und prüfen, z. B. ob heute ein Verkauf stattfindet, ob der Benutzer für den VIP-Status qualifiziert ist, und dann die Logik entsprechend verzweigen, wenn es Zeit ist, auf Daten zuzugreifen, diese zu setzen, sie zu bearbeiten oder einen Kauf durchzuführen. Es sind diese Flags, über die wir sprechen, wenn wir Objekte in Bezug auf die Kapselung einer Reihe von Methoden und persistenten Werten oder Daten diskutieren.
So wie das Modellobjekt Daten verwaltet, um festzustellen, welche Geschäftsregeln im Spiel sind, sollte sich ein Controller, IMO, an allgemeineren Anwendungsstatusdaten festhalten, die sich darauf beziehen, wie sich die App verhalten soll, z. B. ob der Benutzer angemeldet ist oder über ein gültiges Guthaben verfügt Kartendaten vorhanden. Modellmethoden würden in erster Linie den Status dieser Dinge bestimmen, aber es ist sinnvoll, dass der Controller Flags beibehält, die für den allgemeinen App-Fluss relevant sind, wenn sie nicht für den Geschäftsbetrieb oder die Durchführung von Datentransaktionen gelten. Wenn Sie festgestellt haben, dass sie nicht angemeldet sind, sollten Sie das Modell nicht einmal mit Benutzerstatusprüfungen belästigen, bis klar ist, dass ein weiterer Anmeldeversuch durchgeführt wird.
Ebenso mit einem richtigen Ansichtsobjekt im Vergleich zu den typischeren HTML-Vorlagen, die Sie in den meisten serverseitigen Webframeworks sehen. Sobald die Farbeinstellungen des Benutzers geladen sind, sollte es die Ansicht sein, die diese Daten enthält und auf der sie ausgeführt werden. Das Laden, Überprüfen und Ändern von Einstellungen sind Modellprobleme. Sie sollten jedoch nur einmal Modellprobleme sein, bis Änderungen vorgenommen werden.
Laut IMO können Controller keine zusammengesetzten Objekte mit Ansichten und Modellen als interne Aggregatobjekte sein. Dies ist tatsächlich sinnvoll, wenn Sie MVC in einem kleineren Maßstab wie eine UI-Widget-Factory anwenden, da der Controller der ideale Ort ist, um eine Schnittstelle für übergeordnete App-Objekte bereitzustellen und gleichzeitig die Daten und logischen Details der Interaktion von Ansicht und Modell zu vergraben. Für monolothische App-Objekte, bei denen der Controller tatsächlich das Objekt der höchsten Ebene ist, ist dies nicht wirklich sinnvoll.
quelle
So wie ich es verstehe; Das Argument ist komponentenbasierte Architektur im Vergleich zu OOP. Und ohne in den Religionskrieg einzusteigen, denke ich, dass beide dasselbe beschreiben; Ich betrachte es nur aus verschiedenen Blickwinkeln.
Der Sinn von OOP / OOD besteht beispielsweise darin, Ihren Code modularer und wiederverwendbarer zu gestalten. Ja?
Welches ist genau das Ziel der komponentenbasierten Architektur. Sie sind sich also ähnlicher als alles andere.
Ich denke, dass MVC nur die natürliche Entwicklung von OOP ist und wage es, es zu sagen; Eine bessere Möglichkeit, Ihre Objekte zu organisieren, Probleme zu trennen und Code wiederzuverwenden.
quelle
Ich komme zu spät zu dieser Party und unter Berücksichtigung aller Antworten vor meiner, gebe ich zu, dass ich nicht viel Neues zu bieten habe. Es scheint mir jedoch, dass es nicht um das Muster selbst, sondern um die Implementierung geht. MVC an und für sich eignet sich nicht für eine bestimmte Methodik. Tatsächlich kann ich mir einfach prozedurorientierten Code in einem MVC-Muster vorstellen (wie ich es mir vorgestellt habe).
Ich denke also, die eigentliche Frage ist: Sind wir anfälliger für prozeduralen Code, wenn wir das MVC-Muster verwenden?
(und vielleicht bekomme ich nur ein paar runter Stimmen?)
quelle
Nicht anti, sondern auch OOP ist für MVC nicht erforderlich.
Weil Controller, die normalerweise von Classess dargestellt werden, keine Daten enthalten. Wofür reine Funktionen ausreichen würden.
Wenn Sie weiter gehen und Daten vom Verhalten trennen, nehmen wir beispielsweise an, dass Modelle nur Datenbankdaten verarbeiten, die sie jedes Mal abrufen, wenn ihre Funktion (die für die Datenmanipulation verantwortlich ist) aufgerufen wird (stattdessen, um eine Art von Daten in der Instanz zu speichern) Felder) - dann können Sie das gleiche für die Modelle sagen.
Wenn Sie die Ansichtsebene einer Anwendung in ähnlicher Weise unterteilen, werden Sie zu dem Schluss kommen, dass MVC nichts mit OOP zu tun hat, und dass es durchaus möglich ist, die MVC-Implementierung ohne Probleme nur mit einem prozeduralen Ansatz zu schreiben .
quelle
Meiner Meinung nach haben OOPs den Nachteil, dass dies mehr Kopplungseffekt als Kohäsion zeigt, da die (Daten und Verhalten) als eine Einheit (Klasse) geformt sind. Auf der anderen Seite verfügt MVC über ein Modell mit ... (Beans, DAOs, andere Logikklassen), einen Controller, der angibt, wie das Steuerelement verschoben werden muss, und Ansichten, um festzulegen, wie die Daten angezeigt werden sollen, werden getrennt angegeben. Ausgehend davon, ob das Projekt zu groß für die Vorbereitung ist, kann es im Gegensatz zu OOPs einfach als separate Entität erstellt werden. Das Problem wird in logischen Mustern gelöst, genau wie bei der Strategie zum Teilen und Erobern, und MVC folgt diesem Prinzip.
quelle