Es ist möglicherweise nicht die beste Idee, Rails als Grundnahrungsmittel für MVC-Designmuster zu betrachten. Dieser Rahmen wurde mit einigen inhärenten Mängeln erstellt (ich habe ihn in einem anderen Beitrag näher ausgeführt ), und die Community hat gerade erst begonnen, sich mit den Folgen zu befassen. Sie könnten die DataMapper2- Entwicklung als ersten großen Schritt betrachten.
Eine Theorie
Menschen, die diesen Rat geben, scheinen von einem weit verbreiteten Missverständnis betroffen zu sein. Lassen Sie mich zunächst klarstellen: Das Modell ist im modernen MVC-Entwurfsmuster KEINE Klasse oder kein Objekt. Modell ist eine Schicht.
Die Kernidee hinter dem MVC-Muster ist die Trennung von Bedenken, und der erste Schritt darin ist die Trennung zwischen Präsentationsschicht und Modellebene. So wie die Präsentationsschicht in Controller (Instanzen, die für die Benutzereingabe verantwortlich sind), Ansichten (Instanzen, die für die Benutzeroberflächenlogik verantwortlich sind) und Vorlagen / Layouts unterteilt ist, ist auch die Modellebene unterteilt.
Die Hauptteile, aus denen die Modellebene besteht, sind:
Domänenobjekte
Auch als Domänenentitäten, Geschäftsobjekte oder Modellobjekte bekannt (letzterer Name gefällt mir nicht, weil er nur zur Verwirrung beiträgt). Diese Strukturen werden normalerweise fälschlicherweise als "Modelle" bezeichnet. Sie sind dafür verantwortlich, Geschäftsregeln zu enthalten (die gesamte Mathematik und Validierung für eine bestimmte Einheit der Domänenlogik).
Speicherabstraktionen:
Wird normalerweise mithilfe eines Data Mapper- Musters implementiert (nicht mit ORMs verwechseln , die diesen Namen missbraucht haben). Diese Instanzen werden normalerweise mit dem Speichern und Abrufen von Informationen in den Domänenobjekten beauftragt. Jedes Domänenobjekt kann mehrere Mapper haben, genau wie es verschiedene Arten von Speicher gibt (DB, Cache, Sitzung, Cookies, / dev / null).
Dienstleistungen:
Strukturen, die für die Anwendungslogik verantwortlich sind (dh Interaktion zwischen Domänenobjekten und Interaktion zwischen Domänenobjekten und Speicherabstraktionen). Sie sollten wie die "Schnittstelle" wirken, über die die Präsentationsschicht mit der Modellebene interagiert. Dies ist normalerweise das, was in Rails-ähnlichem Code in den Controllern landet.
Es gibt auch verschiedene Strukturen in den Räumen zwischen diesen Gruppen: DAOs , Arbeitseinheiten und Repositories .
Oh ... und wenn wir (im Kontext des Webs) über einen Benutzer sprechen , der mit der MVC-Anwendung interagiert, ist dies kein Mensch. Der "Benutzer" ist eigentlich Ihr Webbrowser.
Was ist also mit Gottheiten?
Anstatt mit einem beängstigenden und monolithischen Modell zu arbeiten, sollten Controller mit Diensten interagieren. Sie übergeben Daten von Benutzereingaben an einen bestimmten Dienst (z. B. MailService
oder RecognitionService
). Auf diese Weise ändert der Controller den Status der Modellschicht, dies erfolgt jedoch mithilfe einer klaren API und ohne Probleme mit internen Strukturen (was zu einer undichten Abstraktion führen würde).
Solche Änderungen können entweder eine sofortige Reaktion hervorrufen oder nur die Daten betreffen, die die Ansichtsinstanz von der Modellebene anfordert, oder beides.
Jeder Dienst kann mit einer beliebigen Anzahl (normalerweise nur eine Handvoll) von Domänenobjekt- und Speicherabstraktionen interagieren. Zum Beispiel RecogitionService
könnte es die Speicherabstraktionen für die Artikel nicht weniger interessieren.
Schlussnotizen
Auf diese Weise erhalten Sie eine Anwendung, die auf jeder Ebene einem Unit-Test unterzogen werden kann, eine geringe Kopplung aufweist (bei korrekter Implementierung) und eine klar verständliche Architektur aufweist.
Beachten Sie jedoch: MVC ist nicht für kleine Anwendungen gedacht. Wenn Sie eine Gästebuchseite mit MVC-Muster schreiben, machen Sie es falsch. Dieses Muster dient zur Durchsetzung von Recht und Ordnung in großen Anwendungen.
Für Personen, die PHP als Primärsprache verwenden, ist dieser Beitrag möglicherweise relevant. Es ist eine etwas längere Beschreibung der Modellebene mit ein paar Codeausschnitten.