Zuallererst habe ich viele Fragen dazu gesehen, aber nicht genug Gründe dafür. Wenn meine Frage nicht gut genug ist und entfernt werden sollte, werde ich verstehen.
Ich habe mir zum Beispiel diese und eine Antwort von mehr als 45 Stimmen angesehen, die besagt, dass er Ihnen rät, die Geschäftslogik in das Modell aufzunehmen, was ziemlich logisch klingt.
Mein erstes großes Projekt habe ich jedoch mit all meinem BL vollständig in den Controllern durchgeführt, da ich diese Dinge nicht in Frage gestellt habe und nachgesehen habe, wie es in AccountController
dem automatisch hinzugefügten Projekt gemacht wird, wenn Sie MVC mit Formularauthentifizierung auswählen. Alle Methoden sehen ziemlich voll mit BL aus. Oder ist es vielleicht die geringste Menge an Code, die hinzugefügt werden konnte, und ich übersehen Dinge?
Eine Person auf Youtube fragte mich, ob er Recht habe, indem er die gesamte Logik in seine Modelle einbaute, und zuerst war ich nein! Dann fing ich an zu denken, dass er vielleicht Recht hatte!?
Wo lege ich meine Geschäftslogik hin? Wenn es sich um Modellklassen handelt, wie viel Code sollte dann in einer Methode, die sich im Controller befindet, als fehlerfreie Menge betrachtet werden? Eine Zeile, um höchstens eine Methode aus dem Modell in einem Controller aufzurufen und dann zur Ansicht zurückzukehren?
quelle
Antworten:
Ich bevorzuge es aus mehreren Gründen, Domänenlogik in das Modell aufzunehmen.
Das Modell sollte keinen UI-Code enthalten und daher einfacher zu testen sein. Wann immer möglich, möchte ich ein voll funktionsfähiges Modell (dh vollständige Testabdeckung) haben, bevor ich einen UI-Code schreibe. Der Controller kann darauf vertrauen, dass das Modell das Richtige tut, und sich nur mit Bedenken hinsichtlich der Benutzeroberfläche befassen.
Wenn Sie Domänenlogik in einen Controller einfügen, ist die gemeinsame Nutzung zwischen verschiedenen Apps oder sogar zwischen verschiedenen Controllern nicht so einfach.
quelle
#2
weil ich es schwierig fand, es selbst zwischen den Controllern zu teilen (ich musste Methoden wie statische verwenden)!Ich mag es, meine Modelle sauber zu halten, dh nur mit Eigenschaften und ohne Geschäftslogik. Ich denke immer, dass es gut ist, Abhängigkeiten in den Controller einzufügen, und diese Abhängigkeiten enthalten die Logik, die ich für meine Modelle ausführe. Ich halte mich nach Möglichkeit gerne an das Prinzip der Einzelverantwortung und finde, dass Modelle mit unzähligen Methoden sehr schnell aufgebläht werden. Für beide gibt es Vor- und Nachteile. Das Einfügen vieler Abhängigkeiten hat einen Overhead, ermöglicht jedoch das isolierte Testen und hält die Klassen einfach, sodass Sie schlankere Controller haben. Obwohl meine Logik in meinem Modell als Mitglieder der Klasse nicht wirklich existiert, ist sie immer noch eine Geschäftslogik. Ich neige dazu, keine Geschäftslogik im Controller zu definieren, da spöttische Dinge wie der Http-Kontext ein Albtraum sind und unnötig.
quelle
Die Geschäftslogik gehört zur Problemdomäne und alles, was zur Problemdomäne gehört, geht in MVC zum Modell .
Der Controller sollte dafür verantwortlich sein, die Daten vom Modell an die Ansicht und von der Ansicht zurück an das Modell zu übergeben. Die Steuerung ist daher die Brücke zwischen der Interaktion des Benutzers und der Modellierung und Speicherung des Problemstatus durch das Programm. Die Klempnerarbeiten sozusagen.
Der Schlüssel hier ist die Unterscheidung zwischen der Geschäftslogik und der Sanitärlogik. Meiner Meinung nach macht der automatisch generierte Account Controller hauptsächlich Klempnerarbeiten, nicht wirklich Geschäftslogik. Beachten Sie, dass die Installationslogik nicht unbedingt kurz ist, sodass Sie keine künstlichen Grenzwerte festlegen müssen (z. B. "X Anzahl der Anrufe höchstens in der Steuerung").
quelle
Als mein Team von Webforms (asp.net) zu mvc wechselte, hat es viel recherchiert und die folgende Struktur entwickelt. Meiner Meinung nach geht es nicht darum, wie groß oder klein die Anwendung ist. Es geht darum, den Code sauber und klar zu halten.
DALProject
AccountsDAL.cs --- > Calls SP or any ORM if ur using any
BLLProject
WebProject
Controller sollten für die Datenübertragung zwischen Modell und Ansicht verantwortlich sein. Ansonsten sollte es keinen unnötigen Code geben. Wenn Sie beispielsweise protokollieren, sollte dies auf Modellebene und nicht auf Controller-Ebene erfolgen.
quelle
Es scheint einige Verwirrung um dieses Thema zu geben. Meistens scheinen die Leute dazu zu neigen, das MVC-Muster mit der N-Tier-Architektur als Entweder-Oder-Situation zu verwechseln. Die Realität ist, dass die beiden Ansätze zusammen verwendet werden können, aber einer nicht vom anderen abhängig ist und auch nicht erforderlich ist.
Die N-Tier-Architektur befasst sich mit der Aufteilung einer Anwendung in mehrere Ebenen. Ein einfaches Beispiel ist die Aufteilung der Anwendung in eine Präsentationsschicht, eine Geschäftslogikschicht und eine Datenzugriffsschicht.
MVC ist ein Entwurfsmuster, das sich mit der Präsentationsschicht einer Anwendung befasst. Es ist durchaus möglich, eine Anwendung nach einem MVC-Ansatz zu entwerfen, ohne Geschäftslogik und Datenzugriffslogik von der Präsentationsschicht zu trennen, und so ein einstufiges Design zu erhalten.
Wenn Sie einen MVC-Ansatz verfolgen, ohne die Anwendung auch in Ebenen zu unterteilen, erhalten Sie Modelle, Ansichten und Controller, deren Geschäftsregeln und Datenzugriffslogik mit dem Rest der Logik gemischt sind.
Per Definition sollte in einer N-Tier-Architektur die Präsentationsschicht nur mit der Geschäftslogikschicht kommunizieren können, sodass festgelegt werden sollte, dass jede der MVC-Komponenten nur mit der Geschäftslogikschicht kommunizieren kann.
Wenn Sie eine Anwendung erstellen, die keine Präsentation und damit keine Präsentationsebene umfasst, sollten Sie sich nicht mit dem MVC-Muster befassen müssen. Möglicherweise teilen Sie Ihre Anwendung jedoch weiterhin in mehrere Ebenen auf und folgen somit einem N-Tier-Design, obwohl keine Präsentationsebene erforderlich ist.
quelle
Im Allgemeinen sollte sich die Geschäftslogik in keinem der MVC-Player befinden. es sollte nur werden verbraucht , indem Sie Ihre Controller - Aktionen.
Wie viele bereits erwähnt haben, ist es am besten, eine Bibliothek zum Hosten von Geschäftslogik als eine Reihe von clientunabhängigen, wiederverwendbaren Komponenten zu erstellen.
Auf diese Weise erhöhen wir die Wiederverwendbarkeit, Kompatibilität, Skalierbarkeit und Testbarkeit mit unserer Software erheblich. Wir reduzieren auch unsere Abhängigkeit von bestimmten Framework-Funktionen, was die Migration auf neuere / andere Technologien erleichtert.
Die Zusammenfassung unserer Geschäftslogik in eine eigenständige Baugruppe (oder Baugruppen) hat uns im Laufe der Jahre gute Dienste geleistet. Unsere Geschäftslogik kann dann von praktisch jeder .NET-Technologie (ASP.NET MVC / API / Core, WPF, Win Forms, WCF, UWP, WF, Konsole usw.) verwendet werden.
Darüber hinaus möchten wir, dass unsere mittlere Ebene Geschäftsregeln und Validierungslogik verarbeitet, um unsere Abhängigkeiten von den .NET MVC Frameworks zu verringern. Beispielsweise vermeiden wir die Verwendung der Validierungshilfen für .NET MVCs und verlassen uns stattdessen auf unsere eigenen. Dies ist ein weiterer Faktor, mit dem wir unsere Geschäftslogik problemlos aus jeder .NET-Technologie nutzen können.
Durch die logische Gestaltung unserer mittleren Ebene auf diese Weise konnten wir diese physische Architektur problemlos erreichen:
Es wurde mit Peasy.NET geschrieben und hat uns über die Jahre gute Dienste geleistet . So gut, dass wir uns für Open Source entschieden haben.
Wenn jemand neugierig ist, wie unsere mittlere Ebene aussieht, finden Sie hier ein Beispiel einer kundenunabhängigen Geschäftsschicht. Außerdem wird der Verbrauch durch mehrere .NET-Clients (ASP.NET MVC, Web Api und WPF) dargestellt.
Hoffe das hilft jemandem!
quelle
Die Geschäftslogik sollte nicht in Ihre Modellansichten oder Controller integriert werden. Es sollte eine separate Business Logic-Schicht vorhanden sein . Der einzige Zweck dieser Ebene besteht darin, Ihre Geschäftslogik zu handhaben. Dies entspricht eher SOLID .
Wenn Sie Ihre Geschäftslogik in MV oder C einfügen, erhalten Sie Code, der schwer zu testen / wiederzuverwenden ist.
Das ist eine schlechte Lösung.
Sie werden in einer Abhängigkeitshölle enden, in der Objekte auf Objekten beruhen.
Selbst wenn Sie eine absolut einfache Funktion haben, müssen Sie dennoch alle Abhängigkeiten erfüllen, um sie aufzurufen.
Außerdem werden unnötige und nicht verwendete Daten ohne Grund weitergegeben. Dies kann sich auch auf die Leistung auswirken, je nachdem, wie schlecht es wird.
Ich sollte auch erwähnen, dass Unit-Tests zu einem Problem werden, da Sie mehrere Objekte verspotten müssen, um eine einfache Funktion zu testen.
Anwendbare Grundsätze des sauberen Codes
Controller
In Ihrem Controller sollten Sie in der Lage sein, die Abhängigkeitsinjektion zum Injizieren der Geschäftslogikschicht zu verwenden . Stellen Sie sicher, dass Ihr Controller nur zum Weiterleiten von Informationen an die Geschäftslogikschicht verwendet wird. Der Controller sollte KEINE Geschäftslogik direkt enthalten. Jede Validierung muss
IValidatable
im Modell durchgeführt werden. Jede Geschäftslogik muss auf eine separate Ebene geleitet werden.quelle
Payment
undProduct
als Instanzvariable? Wie nennt man das Objekt? Wenn ein Modell nicht in einer Ansicht verwendet wird, ist es kein Modell mehr. Es ist Teil einer separaten Schicht. Im Idealfall sollte diese Klasse, die Sie machen, nur das nehmen, was sie von Zahlung und Produkt benötigt, um ihre Arbeit zu erledigen. Wenn es nur dasproductName
und das benötigtprice
, sollte es nur diese beiden Parameter verwenden, nicht das gesamte Objekt.Die allgemeine Antwort, die ich habe, ist, dass Geschäftslogik normalerweise in zwei Kategorien passt:
Objektorientierte Geschäftslogik: Wird als Objekte (im Modell) modelliert und normalerweise als Repositorys eingefügt.
Prozedurale Geschäftslogik: Geht in einen Dienst mit einer Schnittstelle, die in eine Steuerung eingefügt werden kann.
Controller-Logik: Logik, die steuert, wie Befehle empfangen und an die Modelle / Dienste übergeben werden und wie diese Ergebnisse an die Ansicht übergeben werden.
Controller sollten keine Geschäftslogik haben. Dies ist ein sehr spezifischer Teil eines Entwurfsmusters zur Steuerung, wie eine Benutzeroberfläche Eingaben an die Modelle weiterleitet, die mit Geschäftslogik umgehen (oder Services, wenn Ihre Probleme eher prozeduraler Natur sind).
quelle
Ich mag es auch, meine Modelle sauber zu halten (Ref: @Mark Walsh). Das Problem, dass in Controllern eingebettete Logik nicht wiederverwendet werden kann, kann leicht durch Abhängigkeitsinjektion überwunden werden. Wenn Sie der Meinung sind, dass zu viel davon vorhanden ist, können Sie Ihre Geschäfts- / Domänenlogik über Schnittstellen verfügbar machen und das Fassadenmuster in den Controllern verwenden. Auf diese Weise erhalten Sie die Funktionalität, die Sie benötigen, aber halten Sie sowohl die Controller als auch das Modell schön sauber.
quelle
Ich würde es auch vorziehen, Modelle sauber zu halten. Die MVC-Controller sollten nur zum Telefonieren verwendet und sauber gehalten werden. Je nach Wiederverwendbarkeit, Sensibilität und Relevanz kann die Geschäftslogik geschrieben werden
1.WebApi-Controller: Der Vorteil der Verwendung eines Webapi-Controllers besteht darin, dass Sie diese später als Dienste für andere Geräte verfügbar machen können, sodass Ihr Code wiederverwendbar ist.
2. BAL / Common Commonent: Es gibt einige Logiken, die eine bestimmte Verwendung haben und nicht als API verfügbar gemacht werden können. Sie können in dieser Klasse gepusht werden.
3. Repository: Alle datenbankbezogenen Abfragen werden in einem Repository hinzugefügt. Es kann ein generisches Repository geben, das alle Funktionen (CRUD-Operationen) oder bestimmte Repositorys für jede Tabelle implementiert. Abhängig von den auszuführenden Operationen.
quelle
Wie ahanusa schrieb, sollten Sie Ihre Geschäftslogik in eine separate DLL oder ein separates Verzeichnis stellen.
Ich verwende häufig ein Verzeichnis mit dem Namen "Logik" auf derselben Ebene von Modellen und Controllern, in das ich Klassen einfüge, die Geschäftslogiken ausführen.
Auf diese Weise lasse ich sowohl Modelle als auch Steuerungen reinigen.
quelle
Ich weiß, dass es sich um eine Frage zu MVC handelt, aber ich denke, dass das Beispiel, das ich gebe (Web-API), nützlich sein wird.
Ich entwickle meine erste Web-API und verwende die Geschäftslogik aus anderen Anwendungen wieder. Um genau zu sein, es kommt von einer externen DLL, daher wird meine API nur verwendet, um mit einer SAP-Lösung zu "sprechen", Anforderungen von der Bestellung zu empfangen und Antworten zurückzusenden.
Wie kann ich meine (bereits implementierte) Logik in meinen Controller einfügen? Ich brauche es nicht Mein Controller empfängt, validiert nur Anfragen und verfasst Antworten, um Daten zurückzusenden.
Ich arbeite mit ViewModel-Klassen und alles, was sie haben müssen, ist eine Zuordnungsfunktion, um Informationen aus TransferObjects (die von der externen DLL stammen) zu lesen und in ein ViewModel zu übersetzen.
Ich bin mit meiner Anwendung (in diesem Fall der Web-API), die die Geschäftslogik enthält, nicht zufrieden. Ich denke, dass die Wiederverwendbarkeit auf diese Weise verloren geht.
Ich behandle meine Geschäftslogik als eine Abhängigkeit, die ich in den Controller einspeise.
Ich habe das Legacy viel überarbeitet, um eine Unit Testable-Lösung bereitzustellen. Ich musste viele Schnittstellen erstellen und einige Entwurfsmuster in das Legacy implementieren, um diese Lösung bereitzustellen.
Aus meiner Sicht muss die Geschäftsschicht von der Anwendung getrennt sein, vorzugsweise in einer anderen Klassenbibliothek. So haben Sie ein echtes Trennungskonzept in Ihrer Anwendung implementiert.
Wenn Ihr CORE (Geschäft) Ihre Anwendung (API / WebSite) ist , werden die Geschäftsregeln natürlich in Ihre MVC-Klassen implementiert. Wenn Sie jedoch in Zukunft eine neue App entwickeln möchten und einige Geschäftsregeln gleich sind, werden Sie wahrscheinlich viele Probleme haben, nur um die gleiche Logik beizubehalten, die in beiden Anwendungen implementiert ist.
quelle