Repository-Muster mit Service-Schicht - zu viel Trennung?

8

Ich habe eine MVC-Site, die das Repository-Muster verwendet. Ich habe nicht das Gefühl, dass ich den MVC-Stil genug verwende, also mache ich mich bereit, einige davon neu zu entwerfen. Aber ich möchte es auch tun, wenn sich das Frontend jemals ändert, wird es einfacher sein, es auszutauschen.

Folgendes habe ich derzeit

Modelle - Einige meiner Modelle enthalten meine Entitäten / Klassen direkt. (Das Anmeldemodell enthält die Kundenklasse, die eine direkte Korrelation zur Kundentabelle / Repository-Klasse darstellt.) Ansichten - Einige meiner Ansichten enthalten Repo-Abfragen

_customerRepo.Query().FirstOrDefault(c => c.Login == User.Identity.Name);

Controller - Controller, die Repo-Abfragen aufrufen, und einige von ihnen verwenden auch einige Dienste, um die Repos aufzurufen

_customerService.GetAllCustomers()

was anruft

_customerRepo.Query().All();

Hier sind meine Gedanken:

1) Modelle sollten NUR die Daten enthalten, die in der Ansicht dargestellt werden müssen. Selbst wenn alle Eigenschaften der Kundentabelle / des Kundenobjekts in der Ansicht dargestellt werden, sollten sie in ihr eigenes Modell / ihre eigene Klasse neu geschrieben werden, damit die Ansicht nichts über die Datenbankarchitektur oder Backend-Objekte weiß

2) Ansichten sollten nur auf Modellobjekte zugreifen

3) (Und hier kämpfe ich, welchen Weg ich einschlagen soll)

a) Controller (oder irgendwo auf der MVC-Seite sollten Code sein, der die vom Repo / Services zurückgegebenen Objektdaten konvertiert und in die Modelle konvertiert. Ich gehe davon aus, dass ich diesen Code einfach in einen Modellkonstruktor einfügen könnte. Aber ich ' Wir haben festgestellt, dass DI einen leeren Standardkonstruktor erwartet, falls Validierungsfehler auftreten

b) Controller rufen Repo-Schnittstellen für benannte Methoden auf, um Daten abzurufen (dh _customerRepo.GetAllCustomers ()

c) Controller greifen NUR auf eine Service-Schicht zu. Die Service-Schicht ist dann das einzige, was mit der Repo-Schicht interagiert.

Versuche ich, die Ebenen für Modell, Controller, Service und Repo zu stark zu extrahieren? Ist die Serivces-Ebene zu viel Overhead, da alles von den Repos erledigt werden kann?

Was ist der empfohlene Ansatz zum Konvertieren der Objekte / Geschäftsentitäten in die Modelle?

Gander
quelle
2
Meine Antwort auf eine ähnliche Frage: programmers.stackexchange.com/a/135751/4127
Eric King
1
@EricKing das ist genau das, wonach ich gesucht habe. Vielen Dank! Ich würde wahrscheinlich dafür stimmen, diese Frage zu schließen, da es sich wahrscheinlich um ein Duplikat der Frage handelt, zu der Eric einen Link hat.
Ganders
1
Mögliches Duplikat von Separating Data Access in ASP.NET MVC
Mücke

Antworten:

9

Ja, die Serviceschicht ist ein Overhead, wenn Sie dort keine Geschäftslogik haben. Eine geschichtete Architektur sieht aus wie ein Overhead, wenn eine Schicht (in Ihrem Fall Service) nicht viel leistet. Eine geschichtete Architektur bietet jedoch eine lose Kopplung, die im Allgemeinen gut für die zukünftige Anpassung von Anforderungen geeignet ist.

Wenn Sie garantieren können, dass Sie in der Service-Schicht nur Daten kopieren müssen, die vom Repo zum Modell kopiert wurden, können Sie die Service-Schicht in Ihrem Design entfernen. Wenn Ihre Anwendung jedoch einfach ist, müssen Sie sich aus Gründen der Leistung oder aus anderen Gründen keine Gedanken über das Hinzufügen einer weiteren Ebene machen.

Persönlich werde ich die Service-Schicht beibehalten und (abhängig von der Technologie) eine generische DAO / Repository-Schicht implementieren.

Parvez
quelle
Dieser Standpunkt kollidiert mit ddd, wo die Serviceschicht per Definition keine Logik hat und sich die Logik in der Domäne befinden sollte.
Esben Skov Pedersen
2
@EsbenSkovPedersen Es gibt mehr als eine Art von "Service" in DDD. Infrastrukturdienste, Anwendungsdienste und Domänendienste sind nur einige davon. Während Infrastruktur- und Anwendungsdienste keine Geschäftslogik enthalten sollten, können und tun dies Domänendienste.
Eric King
3

Es hängt von Ihren konkreten Repositorys ab, aber im Allgemeinen würde ich eine Service-Schicht über den Repositorys hinzufügen.

Abhängig von Ihrer Repository-Implementierung sind sie möglicherweise spezifisch für Ihren Persistenzspeicher. Es erleichtert auch das Testen und führt zu einer hexagonalen Architektur anstelle einer klassischen Schichtarchitektur (die ich als Vorteil betrachte), siehe https://blog.8thlight.com/uncle-bob/2012/08/13/the- clean -itecture.html .

Kevin Wittek
quelle
Wie zum Teufel könnte der Service spezifisch für den Persistenzspeicher sein? Diese Abstraktion ist genau das, was das Repository bereitstellen sollte. Wenn Ihr Repo Execute (SQL) verfügbar macht, machen Sie es falsch.
Eugene
-4

Um Ihnen ein wenig zu verdeutlichen, was ein Controller ist: MVC stammt aus der Zeit, als wir Mainframes und Textbildschirm-Apps hatten. Das Modell waren die Daten auf dem Mainframe, die Ansicht war der Terminalbildschirm und der Controller war die Tastatur (drücken Sie #, um das Modell zu bearbeiten).

Die Dinge haben sich dahingehend geändert, dass wir heutzutage die Maus verwenden und die Schaltflächen (zur Steuerung der Anwendung) in der Ansicht angezeigt werden.

SuperUser
quelle