Ich habe kürzlich gehört, dass Leute sagen, dass Datenübertragungsobjekte (DTOs) ein Anti-Pattern sind .
Warum? Was sind die Alternativen?
Ich habe kürzlich gehört, dass Leute sagen, dass Datenübertragungsobjekte (DTOs) ein Anti-Pattern sind .
Warum? Was sind die Alternativen?
Antworten:
Einige Projekte haben alle Daten zweimal . Einmal als Domänenobjekte und einmal als Datenübertragungsobjekte.
Diese Vervielfältigung ist mit enormen Kosten verbunden , daher muss die Architektur einen großen Nutzen aus dieser Trennung ziehen, um sich zu lohnen.
DTOs sind kein Anti-Pattern. Wenn Sie einige Daten über das Kabel senden (z. B. an eine Webseite in einem Ajax-Aufruf), möchten Sie sicherstellen, dass Sie Bandbreite sparen, indem Sie nur Daten senden, die vom Ziel verwendet werden. Außerdem ist es für die Präsentationsschicht häufig praktisch, die Daten in einem etwas anderen Format als ein natives Geschäftsobjekt zu haben.
Ich weiß, dass dies eine Java-orientierte Frage ist, aber in .NET-Sprachen ermöglichen anonyme Typen, Serialisierung und LINQ die Erstellung von DTOs im laufenden Betrieb, wodurch die Einrichtung und der Aufwand für deren Verwendung verringert werden.
DTO ein AntiPattern in EJB 3.0 sagt:
Das hohe Gewicht von Entity Beans in EJB-Spezifikationen vor EJB 3.0 führte zur Verwendung von Entwurfsmustern wie Data Transfer Objects (DTO). DTOs wurden zu den leichtgewichtigen Objekten (die eigentlich die Entity-Beans selbst sein sollten), die zum Senden der Daten über die Ebenen verwendet wurden. Mit der EJB 3.0-Spezifikation wird das Entity-Bean-Modell jetzt mit dem einfachen alten Java-Objekt (POJO) identisch. Mit diesem neuen POJO-Modell müssen Sie nicht mehr für jede Entität oder für eine Reihe von Entitäten ein DTO erstellen. Wenn Sie die EJB 3.0-Entitäten über die Ebene senden möchten, implementieren Sie sie einfach java.io.Serialiazable
Ich denke nicht, dass DTOs per se ein Anti-Pattern sind, aber es gibt Antimuster, die mit der Verwendung von DTOs verbunden sind. Bill Dudney nennt die DTO-Explosion als Beispiel:
http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf
Es gibt auch eine Reihe von Missbräuchen von DTOs, die hier erwähnt werden:
http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/
Sie entstanden aufgrund dreistufiger Systeme (normalerweise unter Verwendung von EJB als Technologie) als Mittel zum Übertragen von Daten zwischen Ebenen. Die meisten modernen Java-Systeme, die auf Frameworks wie Spring basieren, verwenden eine alternative vereinfachte Ansicht, bei der POJOs als Domänenobjekte (häufig mit JPA usw. versehen) in einer einzigen Ebene verwendet werden. Die Verwendung von DTOs ist hier nicht erforderlich.
OO-Puristen würden sagen, dass DTO ein Anti-Pattern ist, da Objekte zu Datentabellendarstellungen anstelle von realen Domänenobjekten werden.
Einige betrachten DTOs aufgrund ihres möglichen Missbrauchs als Anti-Muster. Sie werden oft verwendet, wenn sie nicht sein sollten / müssen.
Dieser Artikel beschreibt vage einige Missbräuche.
Wenn Sie ein verteiltes System erstellen, sind DTOs sicherlich kein Anti-Pattern. Nicht jeder wird sich in diesem Sinne entwickeln, aber wenn Sie eine (zum Beispiel) Open Social-App haben, auf der JavaScript ausgeführt wird.
Es wird eine Menge Daten an Ihre API senden. Dies wird dann in eine Form von Objekt deserialisiert, typischerweise ein DTO / Request-Objekt. Dies kann dann überprüft werden, um sicherzustellen, dass die eingegebenen Daten korrekt sind, bevor sie in ein Modellobjekt konvertiert werden.
Meiner Meinung nach wird es als Anti-Muster angesehen, weil es missbraucht wird. Wenn Sie kein verteiltes System erstellen, benötigen Sie diese wahrscheinlich nicht.
Die Absicht eines Datenübertragungsobjekts besteht darin, Daten aus verschiedenen Quellen zu speichern und sie dann sofort in eine Datenbank (oder Remote Facade ) zu übertragen.
Das DTO-Muster verstößt jedoch gegen das Prinzip der Einzelverantwortung , da das DTO Daten nicht nur speichert, sondern auch von oder zur Datenbank / Fassade überträgt.
Die Notwendigkeit, Datenobjekte von Geschäftsobjekten zu trennen, ist kein Gegenmuster, da es wahrscheinlich sowieso erforderlich ist, die Datenbankschicht zu trennen .
Anstelle von DTOs sollten Sie die Aggregat- und Repository-Muster verwenden, die die Sammlung von Objekten ( Aggregat ) und die Datenübertragung ( Repository ) trennen ) .
Um eine Gruppe von Objekten zu übertragen, können Sie das Muster " Arbeitseinheit" verwenden , das eine Reihe von Repositorys und einen Transaktionskontext enthält. um jedes Objekt im Aggregat separat innerhalb der Transaktion zu übertragen.
DTO wird zu einer Notwendigkeit und nicht zu einem ANTI-MUSTER, wenn alle Domänenobjekte die zugehörigen Objekte EAGERly laden.
Wenn Sie keine DTOs erstellen, werden unnötige Objekte von Ihrer Geschäftsschicht auf Ihre Client- / Webschicht übertragen.
Um den Overhead für diesen Fall zu begrenzen, übertragen Sie lieber DTOs.
Die Frage sollte nicht "warum" sein, sondern " wann ".
Auf jeden Fall ist es ein Anti-Muster, wenn nur das Ergebnis der Verwendung höhere Kosten verursacht - Laufzeit oder Wartung. Ich habe an Projekten mit Hunderten von DTOs gearbeitet, die mit Datenbankentitätsklassen identisch sind. Jedes Mal, wenn Sie ein einzelnes Feld hinzufügen möchten, fügen Sie eine ID hinzu, um sie viermal hinzuzufügen - zu DTO, zu Entität, zur Konvertierung von DTO zu Domänenklassen oder Entitäten, zur inversen Konvertierung, ... Sie haben einige der erhaltenen Stellen und Daten vergessen inkonsistent.
Es ist kein Anti-Pattern, wenn Sie wirklich eine andere Darstellung von Domänenklassen benötigen - flacher, reicher, enger, ...
Persönlich beginne ich mit der Domain-Klasse und gebe sie weiter, mit der richtigen Überprüfung an den richtigen Stellen. Ich kann einige "Hilfs" -Klassen mit Anmerkungen versehen und / oder hinzufügen, um Zuordnungen, Datenbanken, Serialisierungsformate wie JSON oder XML vorzunehmen. Ich kann eine Klasse jederzeit in zwei Klassen aufteilen, wenn ich dies für erforderlich halte.
Es geht um Ihre Sichtweise - ich betrachte ein Domänenobjekt lieber als ein einzelnes Objekt, das verschiedene Rollen spielt, anstatt als mehrere Objekte, die voneinander erstellt wurden. Wenn ein Objekt nur Daten transportiert, ist es DTO.
Ich denke, die Leute meinen, es könnte ein Anti-Pattern sein, wenn Sie alle Remote-Objekte als DTOs implementieren. Ein DTO ist nur eine Reihe von Attributen. Wenn Sie große Objekte haben, übertragen Sie immer alle Attribute, auch wenn Sie sie nicht benötigen oder verwenden. Im letzteren Fall bevorzugen Sie die Verwendung eines Proxy-Musters.