Entität zur DTO-Nutzung

15

Ich habe versucht, einen Ablauf für eine grundlegende gestufte Webanwendung zu finden, und habe widersprüchliche Informationen online gelesen. Ich versuche herauszufinden, ob es von Vorteil ist, weiterhin DTO-Objekte von Ihrem DAO-zu-Service-Layer mithilfe einer Art Mapper zu verwenden.

Der grundlegende Ablauf, den ich vorsehe, ist wie folgt:

  1. UI-Modell / Formular -> Controller
  2. Controller konvertiert Modell in Domänenobjekt (Entität)
  3. Domänenobjekt -> Serviceschicht
  4. Domänenobjekt -> DAO
  5. DAO -> Domain Objekt (e)
  6. Service -> Benutzeroberfläche
  7. UI konvertiert Domain in UI-Modelle

Wenn DTO befolgt würde, würde DAO ein DTO zurückgeben, nicht die Entität. Nach einigem Lesen scheint es, als sei DTO ein wenig ausgefallen, da (zumindest in Java) Entities mit Anmerkungen versehene POJOs sind, was bedeutet, dass ihr Speicherbedarf sehr klein geworden ist.

Ist dies der Fall, oder sollten DTOs verwendet werden, um die Domänenobjekte innerhalb der DAO-Schicht vollständig zu kapseln, und wenn dies der Fall ist, was würde die Service-Schicht an die DAO weitergeben?

Vielen Dank!

Dardo
quelle

Antworten:

20

Ein dauerhaftes POJO, wie zum Beispiel eine von JPA verwaltete Bohne, zu übergeben, ist meiner Meinung nach nicht die gute Praxis.

Warum?

Ich sehe drei Hauptgründe:

  1. Mögliches Problem mit faulen Sammlungen. http://java.dzone.com/articles/avoid-lazy-jpa-collections
  2. Entität sollte Verhalten enthalten (im Gegensatz zu einem anämischen Domänenmodell ) Möglicherweise möchten Sie nicht, dass die Benutzeroberfläche unerwartetes Verhalten aufruft.
  3. Im Falle eines anämischen Domänenmodells möchten Sie Ihre Modellstruktur möglicherweise nicht der Benutzeroberfläche anzeigen, da jede neue Änderung am Modell die Benutzeroberfläche beschädigen kann.

Ich bevorzuge es, dass meine Serviceebene Entitäten in beiden Richtungen in entsprechende DTO konvertiert. DAO gibt weiterhin Entität zurück (es ist nicht seine Aufgabe, die Konvertierung sicherzustellen).

Mik378
quelle
Wenn ich das richtig verstehe, befasst sich der Service im Wesentlichen nur mit DTO-Objekten und fungiert als Vermittler zwischen Benutzeroberfläche und DAO. Außerdem müssen Sie in Punkt 3 Ihr DTO noch in funktionsfähige UI-Elemente konvertieren, damit die Benutzeroberfläche bei einem Domain-Update nicht weiterhin beschädigt wird, da DTO ebenfalls ein Update benötigt.
Dardo
1
@dardo UI-Elemente SIND DTO oder sollten schlimmstenfalls in DTO konvertiert werden, bevor einige Dienste auf der Serverseite aufgerufen werden. Es ist unwahrscheinlich, dass sich DTO häufig ändert. Es gibt lediglich Anpassungen Ihrer Entitäten, die sich auf die Anforderungen der Benutzeroberfläche konzentrieren. Außerdem sollte sich die Serviceebene sowohl um DTO als auch um Entitäten kümmern.
Mik378
Ah ok, da ist der Schluckauf, den ich nicht verstanden habe. Anämisches Domänenmodell ist dort, wo ich arbeite, ziemlich verbreitet, und ich versuche, das Paradigma ein wenig zu ändern, um eine dünnere Serviceschicht zu fördern. Danke noch einmal!
Dardo
@dardo Sie können dieses Buch lesen. (oder zeigen Sie es Ihrer Firma;)) Tolles tolles Buch: amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/…
Mik378
Eigentlich habe
ich
13

Einer der Gründe, warum ich denke, dass diese Diskussion immer wieder auftaucht, ist, dass es ein ernstes Problem ist, ein Objekt mit allen benötigten Daten in ein Objekt umzuwandeln, das identisch oder nahezu identisch aussieht du gibst ab

Es ist wahr, es ist eine PITA. Es gibt jedoch einige Gründe (außer den oben genannten), dies zu tun.

  • Domänenobjekte können sehr schwer werden und viele nutzlose Informationen für den Aufruf enthalten. Dieses Aufblähen verlangsamt die Benutzeroberfläche, da alle Daten übertragen, gemarshallt / nicht gemarshallt und analysiert wurden. Wenn Sie in Betracht ziehen, dass ein FE zahlreiche Links zu Ihren Webservices enthält und mit AJAX oder einem anderen Multithread-Ansatz aufgerufen wird, wird Ihre Benutzeroberfläche schnell träge. All dies führt zur allgemeinen Skalierbarkeit von Webservices
  • Die Sicherheit kann leicht gefährdet werden, indem zu viele Daten verfügbar gemacht werden. Zumindest können Sie E-Mail-Adressen und Telefonnummern von Benutzern offenlegen, wenn Sie diese nicht aus dem DTO-Ergebnis entfernen.
  • Praktische Überlegungen: Damit ein Objekt als dauerhaftes Domänenobjekt UND als DTO angezeigt werden kann, müssen mehr Anmerkungen als Code vorhanden sein. Sie haben eine beliebige Anzahl von Problemen beim Verwalten des Status des Objekts, wenn es durch Ebenen geleitet wird. Im Allgemeinen ist dies viel mehr eine PITA-Aufgabe als das mühsame Kopieren von Feldern von einem Domänenobjekt in ein DTO.

Sie können es jedoch relativ effektiv verwalten, wenn Sie die Übersetzungslogik in eine Sammlung von Konvertierungsklassen einkapseln

Schauen Sie sich lambdaJ an, wo Sie 'convert (domainObj, toDto)' ausführen können. Dies ist eine Überladung für die Verwendung mit Sammlungen. Hier ist ein Beispiel für eine Controller-Methode, die davon Gebrauch macht. Wie Sie sehen, sieht es nicht so schlimm aus.

    @GET
    @Path("/{id}/surveys")
    public RestaurantSurveys getSurveys(@PathParam("id") Restaurant restaurant, @QueryParam("from") DateTime from, @QueryParam("to") DateTime to) {

        checkDateRange(from, to);

        MultiValueMap<Survey, SurveySchedule> surveysToSchedules = getSurveyScheduling(restaurant, from, to);
        Collection<RestaurantSurveyDto> surveyDtos = convert(surveysToSchedules.entrySet(), SurveyToRestaurantSurveyDto.getInstance());
        return new RestaurantSurveys(restaurant.getId(), from, to, surveyDtos);

    }
Christian Bongiorno
quelle
Vielen Dank für die Eingabe, und ich denke in die gleiche Richtung =)
dardo