Auch wenn offensichtlich nicht alle Szenarien von einem einzigen Design abgedeckt werden können, wird jetzt im Allgemeinen empfohlen, dass ORM-Klassen zwischen der Präsentations- und der Geschäftsschicht (entweder lokal oder remote) hin- und hergeschickt werden, um die Notwendigkeit von Datenübertragungsobjekten zu ersetzen. So weit ich sehen kann, stellt die Verwendung von ORM-Klassen Probleme mit unnötigem eager loading, Kontextverwaltungsproblemen und enger Kopplung dar, spart jedoch auch eine Menge Zeit und hält die Dinge einfach. Gibt es nun einen Standardansatz, der im Allgemeinen einen der beiden favorisiert (für die Mehrheit der Situationen)?
Antworten
Zu viele Anzeigen?Dies ist eine sehr interessante Frage, mit der ich mich in den letzten beiden Jahren intensiv beschäftigt und experimentiert habe.
Ich denke, es gibt hier wirklich keine richtige oder falsche Antwort. Ich denke nicht, dass man einfach sagen kann, dass man das Eine über das Andere möchte, denn in der Regel möchtest du vielleicht eine Hybridlösung, abhängig davon, wer deine Kunden sind (Webseite, WS, Maschine und/oder lokal, remote).
Das Wichtige hier ist, sich daran zu erinnern, was die Vor- und Nachteile der jeweiligen Angebote sind und dies basierend auf deinen Anforderungen anzuwenden.
Zum Beispiel:
- Wenn du SEAM verwendest, dann möchtest du eine stark geschichtete Architektur vermeiden, da du Zugriff auf einen erweiterten Persistenzkontext hast. Andere Webtechnologien ohne diese Unterstützung funktionieren in der Regel besser mit einem DTO, das den Zustand im Voraus vorbereitet.
- Wenn du eine Remote-Nachricht sendest, ist es wichtig, dass sie dünn und leichtgewichtig bleibt. Ein DTO würde hier in der Regel besser funktionieren als ein komplexes Domänenobjekt. Hier kannst du möglicherweise ORM-Probleme bzw. -verhalten transparent unterdrücken.
- Das DTO-Muster hat den Vorteil, deine Kunden vor Domänenänderungen zu schützen. Dies ist besonders wichtig, wenn deine App ein Webdienst ist, denn ein Domänenobjekt, das deinen Vertrag bestimmt, könnte dich irgendwann im Stich lassen.
Indem du dein System in Schichten verpackst und diese sorgfältig freigibst und sicherst, kannst du verschiedene APIs für viele verschiedene Arten von Kunden erstellen.
Feste Kopplung? Bitte erklär.
Für mich ist DTO ein Anti-Pattern. EJB3 erlaubt uns, ohne sie auszukommen. Sie können einfach Ihre Lazy-Initialisierung erzwingen, bevor Sie das Entity an den Client senden.
Natürlich, wenn Sie nur zwei von 30 Feldern an einen Client senden müssen, senden Sie sie einfach. Aber wenn das immer die gesamten Kopien sind, wie in meinem aktuellen Projekt - versuchen Sie, dieses DTO loszuwerden. Ich sehe keinen Grund, sie zu verwenden. Sie senden ein Geschäftsobjekt an den Client, wie vom Client angefordert. Warum den Wrapper verwenden?
Ich denke, die Existenz von DTOs hängt mit den Fehlern von JPA/Hibernate zusammen. Wenn Sie immer transparente Lazy-Initialisierung durchführen könnten, würden Sie sie nie verwenden. Daher ist die Verwendung von DTOs ein Kompromiss, bei dem mein Domänen-/Arbeitsbereich immer verliert (überall Duplikation). Zusammenfassend: Du kannst sie verwenden, aber du musst sie hassen :)
Ich habe mehrere Bedenken gegen die Verwendung von Entitäten auf der Präsentationsebene:
-
Lock-in: Dies schafft letztendlich eine enge Bindung zwischen Ihrer Präsentation und dem Modell. Es wird teuer, eine Änderung vorzunehmen, in großen Projekten sogar unmöglich. Moderne Tools sind noch nicht ganz da.
-
Sicherheit: Mit Modellobjekten übertragen Sie leicht verschiedene Datenbank-ID-Informationen auf Ihre Webseiten. Dies ist ein klarer Sicherheitsprobleme. Mithilfe von
dto:s
können Sie diese Informationen am Server mit sehr einfachen Session-Maps verstecken. -
Unterschiedliche Bedürfnisse: GUI-Ansichten sind selten direkte Listen von Modellobjekten. Oft sind sie etwas Komplexeres, kombinierte Bestien, guish. Die Bedürfnisse der GUI neigen dazu, in Ihr Modell einzudringen und es zu verdecken.
-
Geschwindigkeit: Mit Entitäten werden bei jedem Lese-/Schreibvorgang jedes Feld verarbeitet. Da Sie sie direkt an die Präsentationsebene übergeben, haben Sie Schwierigkeiten, Ihre JPA-Abfragen zu optimieren - fast unmöglich. Ich werde definitiv zu direktem JDBC-Zugriff zurückkehren - wie bei meinen zukünftigen Projekten mit MyBatis. Das bedeutet die Beseitigung von ORM.
Ich habe auch Bedenken gegen DTO:s
:
- Zusätzlicher DAO-Code.
Alles in allem werde ich für alle Projekte die Verwendung von dto:s
befürworten und auch JPA
beseitigen. Daher sieht mein Stapel etwa so aus:
- MyBatis für den Datenbankzugriff
- POJO als DTO:s
- Stateless EJB für meine DAO-Services
- StatefulEJB für das GUI-Backend
- JSF für die Präsentation
- See previous answers
- Weitere Antworten anzeigen