Di recente ho sentito persone dire che gli oggetti di trasferimento dati (DTO) sono un anti-schema .
Perché? Quali sono le alternative?
Di recente ho sentito persone dire che gli oggetti di trasferimento dati (DTO) sono un anti-schema .
Perché? Quali sono le alternative?
Risposte:
Alcuni progetti hanno tutti i dati due volte . Una volta come oggetti di dominio e una volta come oggetti di trasferimento dati.
Questa duplicazione ha un costo enorme , quindi l'architettura deve trarre un enorme vantaggio da questa separazione per valerne la pena.
I DTO non sono un anti-pattern. Quando si inviano alcuni dati attraverso il cavo (ad esempio, a una pagina Web in una chiamata Ajax), si desidera essere sicuri di conservare la larghezza di banda inviando solo i dati che la destinazione utilizzerà. Inoltre, spesso è conveniente che il livello di presentazione abbia i dati in un formato leggermente diverso rispetto a un oggetto business nativo.
So che questa è una domanda orientata a Java, ma nei linguaggi .NET tipi anonimi, serializzazione e LINQ consentono di creare DTO al volo, il che riduce la configurazione e il sovraccarico del loro utilizzo.
DTO un AntiPattern in EJB 3.0 dice:
La natura pesante di Entity Beans nelle specifiche EJB precedenti a EJB 3.0, ha portato all'utilizzo di modelli di progettazione come Data Transfer Objects (DTO). I DTO sono diventati gli oggetti leggeri (che in primo luogo avrebbero dovuto essere i bean di entità), utilizzati per inviare i dati attraverso i livelli ... ora le specifiche EJB 3.0 rendono il modello di bean di entità uguale al vecchio oggetto Java semplice (POJO). Con questo nuovo modello POJO, non sarà più necessario creare un DTO per ogni entità o per un insieme di entità ... Se si desidera inviare le entità EJB 3.0 attraverso il livello, implementarle semplicemente java.io.Serialiazable
Non credo che i DTO siano di per sé un anti-pattern, ma ci sono antipattern associati all'uso dei DTO. Bill Dudney fa riferimento all'esplosione DTO come esempio:
http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf
Vi sono anche una serie di abusi nei DTO menzionati qui:
http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/
Hanno avuto origine a causa di sistemi a tre livelli (che in genere utilizzano EJB come tecnologia) come mezzo per passare i dati tra i livelli. La maggior parte dei moderni sistemi Java basati su framework come Spring hanno una visione alternativa semplificata usando POJO come oggetti di dominio (spesso annotati con JPA ecc ...) in un unico livello ... L'uso dei DTO qui non è necessario.
I puristi di OO direbbero che DTO è anti-pattern perché gli oggetti diventano rappresentazioni di tabelle di dati anziché oggetti di dominio reali.
Alcuni considerano i DTO un anti-modello a causa dei loro possibili abusi. Sono spesso usati quando non dovrebbero essere / non devono essere.
Questo articolo descrive vagamente alcuni abusi.
Se stai costruendo un sistema distribuito, i DTO non sono certamente un modello anti. Non tutti si svilupperanno in questo senso, ma se disponi di un'app Open Social (ad esempio) che esegue JavaScript.
Pubblicherà un carico di dati nella tua API. Questo viene quindi deserializzato in una forma di oggetto, in genere un oggetto DTO / Request. Questo può quindi essere validato per garantire che i dati inseriti siano corretti prima di essere convertiti in un oggetto modello.
Secondo me, è visto come un anti-pattern perché è usato male. Se non stai costruendo un sistema distribuito, è probabile che non ti servano.
L'intenzione di un oggetto di trasferimento dati è di archiviare i dati da diverse fonti e quindi trasferirli contemporaneamente in un database (o facciata remota ).
Tuttavia, il modello DTO viola il principio di responsabilità singola , poiché il DTO non solo memorizza i dati, ma li trasferisce anche da o verso il database / la facciata.
La necessità di separare gli oggetti dati dagli oggetti business non è un antipattern, poiché è probabilmente necessario separare comunque il livello del database .
Invece di DTO è necessario utilizzare i pattern di aggregazione e repository, che separano la raccolta di oggetti ( aggregazione ) e il trasferimento di dati ( repository ).
Per trasferire un gruppo di oggetti è possibile utilizzare modello Unità di lavoro , che contiene un set di repository e un contesto di transazione; per trasferire ciascun oggetto nell'aggregato separatamente all'interno della transazione.
DTO diventa una necessità e non un ANTI-PATTERN quando tutti gli oggetti del tuo dominio caricano EAGERly oggetti associati.
Se non si effettuano DTO, si avranno oggetti trasferiti non necessari dal livello aziendale al livello client / Web.
Per limitare le spese generali per questo caso, piuttosto trasferire i DTO.
La domanda non dovrebbe essere "perché", ma " quando ".
Sicuramente è anti-pattern quando solo il risultato dell'uso è un costo più elevato - runtime o manutenzione. Ho lavorato su progetti con centinaia di DTO identici alle classi di entità del database. Ogni volta che desideri aggiungere un singolo campo, aggiungi annunci come quattro volte: a DTO, a entità, a conversione da DTO a classi o entità di dominio, la conversione inversa, ... Hai dimenticato alcuni dei luoghi e dei dati ottenuti incoerente.
Non è anti-pattern quando hai davvero bisogno di una diversa rappresentazione delle classi di dominio - più piatta, più ricca, più stretta, ...
Personalmente inizio con la classe di dominio e la passo in giro, con un controllo adeguato nei posti giusti. Posso annotare e / o aggiungere alcune classi "helper" per creare mappature, database, formati di serializzazione come JSON o XML ... Posso sempre dividere una classe in due se ne sento il bisogno.
Riguarda il tuo punto di vista: preferisco guardare un oggetto di dominio come un singolo oggetto che gioca vari ruoli, anziché più oggetti creati l'uno dall'altro. Se l'unico ruolo che un oggetto ha è il trasporto di dati, allora è DTO.
Penso che la gente significhi che potrebbe essere un anti-pattern se si implementano tutti gli oggetti remoti come DTO. Un DTO è semplicemente un insieme di attributi e se si hanno oggetti di grandi dimensioni, si trasferiscono sempre tutti gli attributi anche se non sono necessari o non li si utilizza. In quest'ultimo caso preferisci usare un modello Proxy.