Che cos'è l'oggetto di trasferimento dati?


Risposte:


223

Un oggetto di trasferimento dati è un oggetto utilizzato per incapsulare i dati e inviarlo da un sottosistema di un'applicazione a un altro.

I DTO sono più comunemente utilizzati dal livello Servizi in un'applicazione di livello N per trasferire dati tra se stesso e il livello UI. Il vantaggio principale qui è che riduce la quantità di dati che devono essere inviati attraverso il filo nelle applicazioni distribuite. Fanno anche grandi modelli nel modello MVC.

Un altro uso dei DTO può essere l'incapsulamento dei parametri per le chiamate al metodo. Questo può essere utile se un metodo accetta più di 4 o 5 parametri.

Quando si utilizza il modello DTO, è necessario utilizzare anche assemblatori DTO. Gli assemblatori vengono utilizzati per creare DTO da Domain Objects e viceversa.

La conversione da Domain Object a DTO e viceversa può essere un processo costoso. Se non stai creando un'applicazione distribuita, probabilmente non vedrai grandi benefici dal modello, come spiega Martin Fowler qui


7
"DTO crea modelli fantastici nel modello MVC" - ma un modello non dovrebbe contenere tutti i dati dell'oggetto e DTO dovrebbe essere ottimizzato con parte dei dati? Se ho il modello A e devo passarlo a due sottosistemi, ci saranno A_DTO_1 e A_DTO_2 con i relativi campi di ciascuno? "I DTO possono essere incapsulando i parametri per le chiamate di metodo" -> Quindi ogni classe che avvolge i parametri è DTO anche se questo non è un sistema distribuito? I modelli in MVC non sono l'oggetto di dominio?
Yaron Naveh,

2
In risposta alla tua prima domanda, non credo stessero parlando della stessa cosa. Il modello in MVC non deve necessariamente essere una classe dal tuo modello di dominio. Detto questo, potrebbe anche essere. L'uso del DTO elimina tutte le cose inutili. Dipende solo dall'architettura che stai cercando. Non sono sicuro di come rispondere alla tua seconda domanda. Che sia attraverso il filo o no, è ancora un oggetto che incapsula un mucchio di dati da trasferire tra (sotto) sistemi, quindi direi che è un DTO.
Benny Hallett,

12
"Un altro uso dei DTO può essere l'incapsulamento dei parametri per le chiamate al metodo. Ciò può essere utile se un metodo accetta più di 4 o 5 parametri." Questo è in realtà un anti-modello chiamato classe Poltergeist o Gypsy Wagon. Se il tuo metodo ha bisogno di 4 argomenti, dagli 4, non creare una classe solo per spostare un oggetto in un metodo o in una classe.
Wix,

2
@Wix, buon punto. Direi comunque che questo va bene se è semanticamente corretto (ad esempio se passi una classe di impostazioni con proprietà anziché le proprietà stesse come valori). Quello che non dovresti fare è gettare tutte le argomentazioni a favore del passaggio di un singolo oggetto, dal momento che potrebbero benissimo non essere correlate e causare incubi in seguito.
Aram Kocharyan,

3
I DTO non devono essere utilizzati per incapsulare i parametri per le chiamate di metodi (che li renderebbero LocalDTO), ma sono stati introdotti nel contesto di interfacce remote: martinfowler.com/bliki/LocalDTO.html
Rui

28

La definizione di DTO può essere trovata sul sito di Martin Fowler . I DTO vengono utilizzati per trasferire i parametri ai metodi e come tipi di restituzione. Molte persone usano quelli nell'interfaccia utente, ma altri gonfiano da loro oggetti di dominio.


22

Un DTO è un oggetto stupido - contiene solo proprietà e ha getter e setter, ma nessun'altra logica di alcun significato (tranne forse un'implementazione compare () o equals ()).

Tipicamente le classi del modello in MVC (presupponendo qui .net MVC) sono DTO o raccolte / aggregati di DTO


3
Quello che stai descrivendo è un LocalDTO: martinfowler.com/bliki/LocalDTO.html
Rui

3
Un caso in cui è utile utilizzare qualcosa di simile a un DTO è quando si riscontra una significativa discrepanza tra il modello nel livello di presentazione e il modello di dominio sottostante. In questo caso ha senso creare una facciata / gateway specifici per la presentazione che eseguano il mapping dal modello di dominio e presentino un'interfaccia conveniente per la presentazione.
Amitābha,

14

In generale, gli oggetti valore devono essere immutabili. Come gli oggetti Integer o String in Java. Possiamo usarli per trasferire dati tra livelli software. Se i livelli o i servizi software sono in esecuzione in nodi remoti diversi, ad esempio in un ambiente di microservizi o in un'app Java Enterprise legacy. Dobbiamo fare copie quasi esatte di due classi. Questo è il luogo in cui abbiamo incontrato i DTO.

|-----------|                                                   |--------------|
| SERVICE 1 |--> Credentials DTO >--------> Credentials DTO >-- | AUTH SERVICE |
|-----------|                                                   |--------------|

In passato i DTO di Java Enterprise Systems possono contenere vari elementi EJB.

Non so che questa è una buona pratica o no, ma uso personalmente Value Objects nei miei progetti MVC / Boot Spring come questo:

        |------------|         |------------------|                             |------------|
-> Form |            | -> Form |                  | -> Entity                   |            |
        | Controller |         | Service / Facade |                             | Repository |
<- View |            | <- View |                  | <- Entity / Projection View |            |
        |------------|         |------------------|                             |------------|

Il livello controller non sa quali sono le entità. Comunica con gli oggetti Form e View Value . Form Objects ha annotazioni di convalida JSR 303 (ad esempio @NotNull) e Visualizza oggetti valore hanno Annotazioni Jackson per la serializzazione personalizzata. (ad esempio @JsonIgnore)

Il livello di servizio comunica con il livello del repository utilizzando Entity Objects. Gli oggetti entità hanno annotazioni JPA / Hibernate / Spring Data su di esso. Ogni livello comunica solo con il livello inferiore. La comunicazione tra livelli è vietata a causa della dipendenza circolare / ciclica.

User Service ----> XX CANNOT CALL XX ----> Order Service

Alcuni frame ORM hanno la capacità di proiezione tramite l'utilizzo di interfacce o classi aggiuntive. Quindi i repository possono restituire direttamente gli oggetti View. Lì per te non è necessaria una trasformazione aggiuntiva.

Ad esempio questa è la nostra entità Utente:

@Entity
public final class User {
    private String id;
    private String firstname;
    private String lastname;
    private String phone;
    private String fax;
    private String address;
    // Accessors ...
}

Ma dovresti restituire un elenco di utenti impaginati che includono solo id, nome, cognome. Quindi è possibile creare un oggetto valore vista per la proiezione ORM.

public final class UserListItemView {
    private String id;
    private String firstname;
    private String lastname;
    // Accessors ...
}

È possibile ottenere facilmente il risultato impaginato dal livello repository. Grazie a Spring puoi anche usare solo le interfacce per le proiezioni.

List<UserListItemView> find(Pageable pageable);

Non preoccuparti per il BeanUtils.copymetodo di altre operazioni di conversione funziona bene.


11
  1. Per me la migliore risposta alla domanda che cos'è un DTO è che i DTO sono oggetti semplici che non dovrebbero contenere alcuna logica aziendale o implementazione di metodi che richiederebbero un test .
  2. Normalmente il tuo modello (usando il modello MVC) sono modelli intelligenti e possono contenere molti / alcuni metodi che eseguono in modo specifico alcune operazioni diverse per quel modello (non la logica aziendale, questo dovrebbe essere nei controller). Tuttavia, quando si trasferiscono dati (ad es. Chiamando un endpoint REST ( GET/ POST/ qualunque cosa) da qualche parte o consumando un servizio Web utilizzando SOA, ecc ...) non si desidera trasmettere l'oggetto di grandi dimensioni con codice non necessario per l'endpoint, consumerà i dati e rallenterà il trasferimento.

Perché la logica aziendale dovrebbe essere nei controller?
AlexioVay

6

Con MVC gli oggetti di trasferimento dati vengono spesso utilizzati per mappare i modelli di dominio su oggetti più semplici che alla fine verranno visualizzati dalla vista.

Da Wikipedia :

Il Data Transfer Object (DTO), precedentemente noto come oggetti valore o VO, è un modello di progettazione utilizzato per trasferire dati tra sottosistemi di applicazioni software. I DTO vengono spesso utilizzati insieme agli oggetti di accesso ai dati per recuperare i dati da un database.


3
Un oggetto valore non è un DTO .
coderpc,

0

L'oggetto trasferimento dati (DTO) descrive "un oggetto che trasporta dati tra processi" (Wikipedia) o un "oggetto utilizzato per incapsulare i dati e inviarli da un sottosistema di un'applicazione a un altro" (risposta Stack Overflow).


0

defn

Un DTO è un modello di dati hardcoded . Risolve solo il problema della modellazione di un set di dati gestito da un processo di produzione hardcoded , in cui tutti i campi sono noti in fase di compilazione e quindi accessibili tramite proprietà fortemente tipizzate.

Al contrario, un modello dinamico o "property bag" risolve il problema della modellazione di un set di dati quando il processo di produzione viene creato in fase di esecuzione.

Il Cvar

Un DTO può essere modellato con campi o proprietà, ma qualcuno ha inventato un contenitore di dati molto utile chiamato Cvar. È un riferimento a un valore. Quando un DTO è modellato con quelle che chiamo proprietà di riferimento , i moduli possono essere configurati per condividere la memoria heap e quindi collaborare su di essa. Questo elimina completamente il passaggio dei parametri e la comunicazione O2O dal tuo codice. In altre parole, i DTO con proprietà di riferimento consentono al codice di raggiungere l'accoppiamento zero .

    class Cvar { ... }

    class Cvar<T> : Cvar
    {
        public T Value { get; set; }
    }

    class MyDTO
    {
        public Cvar<int> X { get; set; }
        public Cvar<int> Y { get; set; }
        public Cvar<string> mutableString { get; set; } // >;)
    }

Fonte: http://www.powersemantics.com/

I DTO dinamici sono un componente necessario per il software dinamico. Per creare un'istanza di un processo dinamico, un passaggio del compilatore consiste nell'associare ogni macchina nello script alle proprietà di riferimento definite dallo script. Un DTO dinamico viene creato aggiungendo i Cvar a una collezione.

    // a dynamic DTO
    class CvarRegistry : Dictionary<string, Cvar> { }

contese

Nota: poiché Wix ha etichettato l'uso di DTO per l'organizzazione dei parametri come "anti-pattern", darò un parere autorevole.

    return View(model);  // MVC disagrees

La mia architettura collaborativa sostituisce i modelli di progettazione. Fare riferimento ai miei articoli Web.

I parametri forniscono il controllo immediato di una macchina con telaio a pila. Se si utilizza il controllo continuo e quindi non è necessario un controllo immediato, i moduli non richiedono parametri. La mia architettura non ne ha. La configurazione in-process delle macchine (metodi) aggiunge complessità ma anche valore (prestazioni) quando i parametri sono tipi di valore. Tuttavia, i parametri del tipo di riferimento fanno sì che il consumatore causi errori nella cache per ottenere comunque i valori dall'heap - quindi, è sufficiente configurare il consumatore con proprietà di riferimento. Fatti dall'ingegneria meccanica: fare affidamento sui parametri è una sorta di preottimizzazione, poiché l'elaborazione (fabbricazione dei componenti) stessa è uno spreco. Consultare il mio articolo W per ulteriori informazioni. http://www.powersemantics.com/w.html .

Fowler e la compagnia potrebbero realizzare i benefici dei DTO al di fuori dell'architettura distribuita se avessero mai conosciuto un'altra architettura. I programmatori conoscono solo i sistemi distribuiti. I sistemi collaborativi integrati (ovvero produzione o produzione) sono qualcosa che ho dovuto rivendicare come mia architettura, perché sono il primo a scrivere codice in questo modo.

Alcuni considerano il DTO un modello di dominio anemico, nel senso che manca di funzionalità, ma questo presuppone che un oggetto debba possedere i dati con cui interagisce. Questo modello concettuale ti costringe quindi a fornire i dati tra gli oggetti, che è il modello per l'elaborazione distribuita. Tuttavia, su una linea di produzione, ogni passaggio può accedere al prodotto finale e modificarlo senza possederlo o controllarlo. Questa è la differenza tra elaborazione distribuita e integrata. La produzione separa il prodotto dalle operazioni e dalla logistica.

Non c'è nulla di intrinsecamente sbagliato nell'elaborazione della modellazione come un gruppo di inutili impiegati che si scambiano e-mail l'uno con l'altro senza tenere una traccia di e-mail, tranne tutto il lavoro extra e il mal di testa che crea nella gestione della logistica e dei problemi di restituzione. Un processo distribuito correttamente modellato allega un documento (instradamento attivo) al prodotto che descrive le operazioni da cui provengono e verranno eseguite. Il routing attivo è una copia del routing di origine del processo, che viene scritto prima dell'inizio del processo. In caso di un difetto o altra modifica di emergenza, il routing attivo viene modificato per includere le fasi operative a cui verrà inviato. Ciò rappresenta quindi tutto il lavoro che è andato in produzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.