Service Layer vs DAO - Warum beides?

64

Ich habe mit SpringMVC, Hibernate und einigen Datenbanken in einem Java-Webanwendungsbeispiel gearbeitet.

Es gibt ein paar verschiedene, die dies tun, aber dieses Spring-3- und Hibernate-Integrationstutorial mit Beispiel enthält eine Modellklasse, eine Ansicht (in jsp) sowie eine Service- und eine Dao-Klasse für den Controller.

Meine Frage ist, machen nicht sowohl die Service- als auch die DAO-Klasse dasselbe? Warum brauchst du beide?

Dies war das Tutorial, das ich tatsächlich verwendete: http://fruzenshtein.com/spring-mvc-security-mysql-hibernate/

Jeff
quelle

Antworten:

60

Im Allgemeinen ist das DAO so leicht wie möglich und dient nur dazu, eine Verbindung zur Datenbank herzustellen. Manchmal wird es abstrahiert, sodass verschiedene DB-Backends verwendet werden können.

Die Serviceschicht ist dazu da, Logik bereitzustellen, um mit den Daten zu arbeiten, die an und von der DAO und dem Client gesendet werden. Sehr oft werden diese 2 Teile zu demselben Modul und gelegentlich zum selben Code zusammengefasst, aber Sie werden sie immer noch als unterschiedliche logische Einheiten sehen.

Ein weiterer Grund ist die Sicherheit. Wenn Sie eine Serviceschicht bereitstellen, die keine Beziehung zur Datenbank hat, ist es schwieriger, vom Client außer über den Service auf die Datenbank zuzugreifen. Wenn auf die Datenbank nicht direkt vom Client aus zugegriffen werden kann (und kein einfaches DAO-Modul als Dienst fungiert), versucht ein Angreifer, der den Client übernommen hat, auch die Dienstschicht zu hacken, bevor er alle außer der erhält am meisten bereinigten Zugang zu Ihren Daten.

gbjbaanb
quelle
1
Ich bin mit der Trennung von Service- und Dao-Ebenen und Ihrer Service-Ebene, die Ihre Geschäftslogik enthält, einverstanden.
Peter Delaney
Ganz zu schweigen davon, dass ein Dienst möglicherweise mehrere DAOs aufruft. Wenn Sie beispielsweise einen Benutzer speichern, können Sie mit UserDao, UserOrdersDao usw. sprechen. Oder sollten wir für jeden einen Dienst erstellen? Und wer könnte dann all diese Dienste anrufen?
Fermin Silva
40

Ich bin der Verfasser der fraglichen Post. Ich habe meinen gerechten Anteil an der Arbeit an verschiedenen Technologien und verschiedenen Architekturen. Aufgrund der obigen Ausführungen kann ich mit Sicherheit sagen, dass es immer eine gute Idee ist, eine Service- und eine Dao-Schicht zu haben. DAO sollte auf das Hinzufügen / Aktualisieren / Einfügen / Auswählen von Entitätsobjekten in / aus der Datenbank beschränkt sein, und das ist alles. Wenn Sie weitere logische Schritte ausführen möchten, fügen Sie diese der Serviceebene hinzu. Dies hilft dabei, den Code modular zu gestalten und beim Ersetzen der Datenbank (für einen Teil der Daten) leicht zu ersetzen. Dies gilt insbesondere für Anwendungen mit Berichten, die auch nach dem Abrufen von Daten aus der Datenbank eine hohe Logik aufweisen.

Auch im Frühjahr wird Sicherheit in der Serviceschicht ideal angewendet. Sie möchten diesen Weg nicht ändern.

lokesh
quelle
5
Hey, vielen Dank für die Beantwortung meiner Frage. Das ist Hingabe an Ihren Blog! Vielen Dank für das großartige Beispiel. Schreiben Sie weiter.
Jeff
Das hat mich einige Zeit beschäftigt und ich denke, Erfahrung hilft in diesen Situationen am meisten. Danke.
Utku Özdemir
Ich bin mit der Trennung von Service- und Dao-Ebenen und Ihrer Service-Ebene, die Ihre Geschäftslogik enthält, einverstanden und würde nur Dao-Methoden aufrufen. Was ist, wenn eine meiner Dienstmethoden eine andere Dienstmethode aufrufen muss? Sollte ich über der Serviceschicht eine weitere Abstraktion haben, die mehrere Servicemethoden aufruft?
Peter Delaney
Nein. Klassen auf Serviceebene können (je nach Bedarf) voneinander referenziert sein und die erforderlichen Methoden aufrufen.
Lokesh
11

Adam Bien weist in seinem Buch darauf hin, dass der JPA EntityManager eine gute universelle Implementierung des DAO darstellt:

http://realworldpatterns.com/

In der Java EE-Welt muss fast nie ein eigenes DAO geschrieben werden, da JPA-Implementierungen eines enthalten. Sie müssen nur die Serviceschicht schreiben.

Das Implementieren einer eigenen DAO-Schicht ist wirklich ein Kater der sehr schlechten J2EE-Architektur von vor 15 Jahren, aber viele Menschen fühlen sich immer noch dazu gezwungen. Diese benutzerdefinierten DAO-Ebenen bieten häufig nur Weiterleitungsfunktionen, die die entsprechende Methode in EntityManager aufrufen.

Um Ihre Frage zu beantworten, benötigen Sie eine Service-Schicht und eine DAO, aber Sie müssen nur die Service-Schicht schreiben.

Dean Schulze
quelle
2
Ich bin mir nicht sicher, ob dies für Spring gilt - es muss immer ein benutzerdefiniertes DAO für das Modell erstellt werden. Vielleicht gilt Ihre Aussage "Es ist fast nie nötig, ein eigenes DAO zu schreiben" speziell für EJB-Container / Anwendungsserver?
Don Cheadle
1
Es ist besser, ein eigenes (DAO / DAOImpl) zu schreiben, obwohl es nur EntityManager zugeordnet werden kann, da Sie in Zukunft eine weitere DAO-Implementierung hinzufügen können, ohne den Service-Layer-Code ändern zu müssen .
ahmednabil88
@YajliMaclo Was ist der Unterschied, was zu ändern?
Alex78191
4

Normalerweise füge ich allen db-spezifischen Code (Abfragen) in DAOs und die Transaktionsbehandlung und Geschäftslogik in Services ein. Dies ermöglicht Service-Methoden, Methoden über mehrere Daos aufzurufen und alles in derselben Transaktion zu belassen. Meiner Meinung nach ermöglicht dies eine bessere Wiederverwendung von Code in Daos.

sbrattla
quelle
2

Ich habe festgestellt, dass die Service-Schicht in den meisten Fällen unnötige Komplexität hinzufügt. Theoretisch sollte vermieden werden, dass die Unternehmenslogik in der Dao-Schicht enthalten ist. Letztendlich führt dies jedoch nur zu Verwirrung. Selbst einige Leute haben es nicht gewohnt, die Dao-Schicht vollständig zu entfernen, da sie der Meinung sind, dass sie keinen Mehrwert bringt. http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer

Aber wenn Sie mehrere Geschäftslogiken haben, dann ist es eine gute Idee. Wie wichtig ist es, eine Serviceschicht zu erstellen?

Jesus
quelle
3
Ich habe Ayendes Blog-Post schon mehrmals gelesen und kann das Gefühl nicht loswerden, dass sein Design (dem ich an einem Punkt zugestimmt hätte), obwohl es dem Geist von YAGNI treu geblieben ist, fast zwangsläufig mehr Entwicklungszeit kosten würde Mittelfristig, als es kosten würde, die Abstraktion von Schichten an erster Stelle einzurichten. Ich frage mich, ob er seine Meinung zu einer engen Kopplung zwischen der gesamten Anwendung und NHibernate geändert hat, da es für eine einzelne Anwendung noch häufiger ist, mehrere SQL-, NoSQL- und API-Datenquellen abzufragen.
Mr Cochese
@LennyGodber Ja, ich weiß, dass Sie der Meinung sind, dass es besser ist, die DAO- / Repository-Ebene zu haben, da dies mehr Vorteile als Nachteile hat, da es, wie Sie sagten, sehr häufig ist, mehrere Datenquellen zu haben
Jesus,
-1

IMHO kann die Service-Schicht als Schicht zwischen dem Controller und der DAO-Schicht betrachtet werden. Auf dieser Service-Ebene können wir Geschäftslogik hinzufügen und sogar ein Rückgabeobjekt erstellen, das genau darauf abgestimmt ist, was von der Ansicht gerendert werden muss.

compserve23
quelle