Wo soll ich eine API-Anfrage in MVC stellen?

25

Ich erstelle eine Webanwendung mit einem MVC-Muster. Nach dieser Art von Architektur können wir sehen, dass alle Methoden, die zur Interaktion mit der Datenbank verwendet werden, im Modell implementiert sind .

Aber was passiert, wenn ich einen Dienst anrufen muss, der von anderen im Web angezeigt wird? Zum Beispiel möchte ich auf die Facebook-API zugreifen, um alle Follower meiner Seite zu erhalten. Wo lege ich diese Methoden ab?

Offensichtlich ist die Ansicht keine gute Idee, da dieses Modul der Präsentation gewidmet ist. Der Controller sollte nicht zum Abrufen von Daten verwendet werden, sondern das Modell ist normalerweise nur der Interaktion mit der Datenbank gewidmet.

Können Sie mir einen Hinweis dazu geben? Und bitte, können Sie mir sagen, ob ich Fehler in Bezug auf die MVC-Architektur mache?

Ema.jar
quelle
2
Ich denke, die Leute könnten bessere Antworten geben, wenn Sie einige der Bibliotheken und Frameworks auflisten würden, die Sie zur Unterstützung Ihrer MVC-Anwendung verwenden. Obwohl das MVC-Muster technologieunabhängig ist, folgen ihm nicht alle Frameworks explizit. Darüber hinaus verfügen die meisten ausgereiften Frameworks bereits über eine hervorragende Dokumentation. Wenn Sie wissen, welches Framework Sie verwenden, können Sie leichter auf eine bereits vorhandene Erklärung verweisen, die Ihrer Denkweise entspricht.
CLW
2
Datenbank? Datenquelle? Es sind nur Daten.
2
Es gibt so viele Meinungen darüber, was "MVC" sein soll, dass diese Frage zu abstrakt ist, um sie zu beantworten.
RemcoGerlich
2
Erwägen Sie auch, die API von Ihrem Front-End-Javascript-Code aus aufzurufen und zu verhindern, dass sie Ihre Back-End- "MVC" -Stücke berührt.
RemcoGerlich
@Remcogerlich deshalb habe ich vorgeschlagen, die eigentliche Implementierung, die er sich ansieht, hinzuzufügen. Es könnte sich um ein Backend und eine Frontend-Implementierung von MVC handeln. Wir könnten auch ein anderes Muster haben, das diese Unterschiede besser erklärt.
CLW

Antworten:

37

Das Modell ist nicht auf die Interaktion mit der Datenbank beschränkt, sondern für das Abrufen und Bearbeiten von Daten verantwortlich.

Für Ihre Ansicht und Ihren Controller sollte es also keinen Unterschied machen, ob die Daten aus einer Datenbank oder einem Webservice stammen oder sogar völlig zufällig sind. Deshalb sollten Sie dies im Modell tun.

MVC ist ein Präsentationsmuster, das nur die verschiedenen Darstellungsebenen voneinander trennt.

Dies bedeutet nicht, dass das Modell ein einheitliches Durcheinander von Spaghetti-Code sein muss. Ihr Modell selbst kann auch geschichtet werden, der Controller sollte jedoch nicht wissen, woher die Daten stammen.

Eine öffentliche Methode in Ihrem Modell kann wie folgt aufgebaut sein (Pseudocode), der von Ihrem Controller aufgerufen werden kann:

public MyDataClass getData(int id) {
    WebServiceData wsData = WebService->getData(id);
    DatabaseData dbData = ORM->getData(id);
    return new MyDataClass(wsData, dbData);
}

WebServiceund ORMmüssen möglicherweise Instanzen von Schnittstellen sein, die durch Mocks per Abhängigkeitsinjektion ersetzt werden können, aber Ihre Controller und Ansichten müssen sich zu Testzwecken nicht ändern.

Residuum
quelle
8
Das Modell sollte keine Logik haben und daher nicht direkt mit irgendetwas interagieren. Das MVC-Muster fordert eindeutig, dass die gesamte Logik in Steuerungen platziert wird. Diese Controller sollten sich mit der Datenbank, der API usw. in Verbindung setzen und das Modell nach Bedarf aktualisieren. Dies hält Ihre Modelltechnologie agnostisch und stellt sicher, dass sie lediglich als Speichermechanismus dient, der zur Präsentation an verschiedene Ansichten und zur zusätzlichen Manipulation an Steuerungen übergeben werden kann.
CLW
3
@CLW: Model! = Datenmodell. Weitere Details finden Sie an anderer Stelle, z. B. stackoverflow.com/a/14045514/124983
Residuum
2
@CLW: Geschäftslogik sollte nicht in M, V oder C sein. Modelle sind eine Abstraktion eines Datenspeichers, Ansichten und Controller sind Ihre Benutzeroberfläche. Sie sind die Peripherie der eigentlichen Anwendung, die Sie erstellen. Dies sollte "nur Code" sein, der nichts über Datenbanken und das Web wissen muss.
RemcoGerlich
2
Der "Modell" -Teil wird auf viele hundert verschiedene Arten interpretiert. Mir wurde immer beigebracht, dass ein Modell eine Repräsentation ist. Ein Modellzug ist eine Darstellung eines realen Zuges mit kleinen beweglichen Teilen, die sich genau wie der reale bewegen. In ähnlicher Weise ist das Modell in Ihrer App eine Darstellung der Systeme und Prozesse, zu deren Ersetzung Sie Ihre Software erstellen. Als solche haben Modelle Verhalten . Dieses Verhalten beinhaltet Ihre "Geschäftslogik". Wenn Sie also reinen CRUD-Datenzugriff, Benutzeroberfläche und Interop ignorieren, bleibt wahrscheinlich Ihr "Modell" übrig - Domänenklassen, Geschäftsregeln usw.
anaximander
1
@RemcoGerlich Ich habe nichts über Geschäftslogik gesagt. Da die meisten Interpretationen von MVC voraussetzen, dass das Modell nur eine einfache Struktur ist, die Ihren Anwendungsstatus darstellt, sollte die Verantwortung für die Kontaktaufnahme mit der Datenbank, der API usw. nicht im Modell liegen, da dies der Fall sein sollte Logik frei. Die Pflicht zur Kommunikation mit der Datenbank sollte entweder beim Controller oder einem anderen vom Controller verwalteten Objekt liegen.
CLW
12

Es gibt ein allgemeines (absichtliches?) Missverständnis darüber, was M, V und C sind. Nicht über die Rollen, die sie einnehmen, aber was sind sie.

In der ursprünglichen Desktop-GUI-Definition von MVC handelte es sich um Module . In der Regel gab es in einer Anwendung mehrere, manchmal in Drillingen, manchmal mit einer Vielzahl von Ansichten und Modellen, die von einigen Controllern gemischt und abgeglichen werden konnten.

In Web-Frameworks (OTOH) werden sie in der Regel als Ebenen betrachtet , in denen sie jeweils nur eine sind. Dabei geht es hauptsächlich um die Abdeckung einer untergeordneten Abstraktionsebene: "Die Modellebene abstrahiert die Datenbank", "Die Ansichtsebene implementiert die Präsentation" und "Der Controller" Ebene verarbeitet Benutzereingaben ".

Ich würde also sagen, dass Sie bereits ein Modell für die Interaktion mit der Datenbank haben und jetzt nur noch ein anderes Modell erstellen müssen, um mit Ihrer Quell-API fertig zu werden. Wenn Sie sie so ähnlich wie möglich gestalten, können die meisten Controller- und View-Codes nahtlos mit beiden Modellen zusammenarbeiten.

Javier
quelle
1
Einverstanden: Die Modelle sollten immer die gesamte Problemdomäne sein. In komplizierten Apps sollte es immer der Hauptteil des Codes sein. Sie bestanden aus dem gesamten Code, der sich nicht ändern würde, wenn Sie die Benutzeroberfläche ändern (z. B. von der Website zur GUI oder sogar zur Befehlszeilenanwendung). Denken Sie an einen Compiler. Nur ein sehr kleiner Teil des Codes würde sich ändern, wenn Sie von einer Befehlszeilen-Benutzeroberfläche zu einer GUI oder sogar zu einer Web-Benutzeroberfläche wechseln. Das A und O einer solchen Anwendung sind die Modelle.
Kevin Cathcart
1
In der ursprünglichen Smalltalk-Verwendung des Begriffs hatte jedes UI-Steuerelement in der Benutzeroberfläche ein eigenes Modell, eine eigene Ansicht und einen eigenen Controller.
RemcoGerlich
5

Ein Teil der Schwierigkeit bei jeder Diskussion über MVC besteht darin, dass verschiedene Gruppen sich dafür entschieden haben, unterschiedliche Bedeutungen zu haben. Die Implementierung von MVC, die beispielsweise in einer Rails-App verwendet wird, ist für jemanden, der eine Swing-App schreibt, fast nicht wiederzuerkennen. In dem Maße, in dem MVC immer noch eine genau definierte Sache ist, handelt es sich eher um eine Reihe von Leitprinzipien (trennen Sie die Kernanwendung von ihrer visuellen Darstellung, stellen Sie flexible Mechanismen zur Verfügung, mit denen beide zusammenarbeiten können), die in verschiedenen Varianten implementiert werden können Wege.

In der Tat gibt es die Tendenz, verschiedenen MVC-abgeleiteten Designs unterschiedliche Namen zu geben (siehe diesen Artikel von Martin Fowler für eine Diskussion darüber) oder sogar auf eine präzise Benennung zu verzichten - zum Beispiel beschreibt sich AngularJS selbst als Model-View-Whatever Rahmen.

Daher ist es schwierig zu antworten, ohne zu wissen, mit welcher Version von "MVC" Sie arbeiten. Eine API-Anforderung ist jedoch normalerweise Teil der Kernanwendung (der Teil, der sich nicht ändern sollte, wenn Sie sich für eine andere visuelle Darstellung entscheiden), die in vielen Implementierungen vollständig im Modell enthalten ist.

James_pic
quelle
2

Hier wird das Modell folgendermaßen beschrieben:

Ein Modell speichert Daten, die auf dem Controller abgerufen und in der Ansicht angezeigt werden. Bei jeder Änderung der Daten wird diese vom Controller aktualisiert.

Ich würde sagen, dass der Controller entweder die Logik zum Aufrufen des Dienstes enthält oder ein separates ServiceObjekt aufruft . Wenn der Dienst separat ist, können Sie einfacher Tests erstellen, z. B. wenn keine Verbindung zu einem Dienst über ein Netzwerk möglich ist, können einige lokal TestServiceantworten Service.

Lesen Sie auch diese Antwort, die darauf hindeutet, dass der Controller den Dienst aufruft.

Null
quelle
2

Ihr Modell sollte niemals tatsächlichen Code enthalten und eher als Nachricht oder Struktur zur Verwaltung von Inhalten angesehen werden, die vom Controller manipuliert und von der Ansicht angezeigt werden.

Ihr Controller sollte für die Kontaktaufnahme mit APIs, Datenbanken, Diensten usw. verantwortlich sein, um eine Änderung anzufordern und alle erforderlichen Aktualisierungen des Modells zu verwalten.

Die gesamte Stärke des MVC-Musters besteht darin, dass es die Logik (den Controller) von der Ansicht und dem Status (dem Modell) entkoppelt. Auf diese Weise haben Sie jetzt die Garantie, dass nur Code im Controller Nebenwirkungen hervorrufen kann, da die Ansicht und das Modell einfach keine Änderungen vornehmen dürfen.

Es ermöglicht auch eine bessere Wiederverwendung von Code, da ein Modell von verschiedenen Controllern und Ansichten gemeinsam genutzt werden kann.

CLW
quelle
4
Ich denke, wenn Sie hier "Modell" sagen, beziehen Sie sich auf "Ansichtsmodell", welches IMO eine separate Sache ist. Ein Ansichtsmodell ruft Daten vom Controller in die Ansicht ab und ist als solches entweder ein Implementierungsdetail der Ansicht oder ein Aspekt der Kommunikation zwischen Ansicht und Controller, der nicht wirklich zu beiden passt (hängt davon ab, wie Sie es sehen). Das "Modell" in MVC bezieht sich auf ein Systemmodell - eine Darstellung des Systems, das Daten, Struktur und Verhalten enthält. Das Modell ist Zustand und Logik; Der Controller bewirkt, dass die Logik ausgeführt wird und sich der Status ändert, wenn die Ansicht bearbeitet wird.
Anaximander
@anaximander Nein, ich beziehe mich in einer recht strengen Interpretation von MVC auf das Modell (siehe Wikipedia, Microsoft MVC, Muster für Head-First-Designs usw.). In diesen Fällen ist das Modell nichts anderes als eine einfache Struktur zum Übergeben von Daten herum und es gibt kein Ansichtsmodell. Die Microsoft MVC-Implementierung fügt dem Modell zwar verschiedene Attribute hinzu, dies dient jedoch in erster Linie der Benutzerfreundlichkeit. Am Ende bestand der Zweck des MVC-Musters darin, bewährte Methoden zur Codetrennung zu vereinfachen und Nebenwirkungen zu begrenzen.
CLW
1

Könnte hier weit weg sein, aber so sehe ich WebApps und die Arbeit mit [komplexen] Remote-APIs in vielen Fällen:

Ich würde es zu einer Klasse (dh einer Bibliothek von Methoden zur Datenreduzierung) anstatt zu einem Modell (dh einem Stapel von Funktionen zur Datenreduzierung) machen. Es scheint, als würde es transparenter, logischer / schemaunabhängiger wirken, und Sie könnten es überall verwenden, ohne jedes Mal, wenn Sie es verwenden möchten, ein Modell / einen Controller selbst aufzurufen. Die Logik ist immer noch getrennt, der Datenpunkt ist immer noch flexibel und es scheint offener für Interoperabilität in seltsamen Fällen wie dem Stapeln von clientAJAX-> appJSON-> appLIB-> remoteAPI-> remoteJSON usw., um den Endpunkt indirekt abzufragen.

Dhaupin
quelle