2015-01-22 28 views
7

Da ciò che ho letto e implementato, DTO è l'oggetto che contiene un sottoinsieme di valori da un modello Data, nella maggior parte dei casi questi sono oggetti immutabili.Quando è opportuno mappare un DTO alla controparte Entity

E il caso in cui ho bisogno di passare un nuovo valore o modifiche al database?

Devo lavorare direttamente con il modello dati/entità reale dal mio DAL nel mio livello Presentazione?

Oppure devo creare un DTO che può essere passato dal livello di presentazione al livello aziendale, quindi convertirlo in un'entità, quindi essere aggiornato nel DB tramite una chiamata ORM. È scritto troppo codice? Suppongo che ciò sia necessario se il livello di presentazione non ha alcun concetto del modello di dati. Se stiamo seguendo questo approccio, dovrei recuperare nuovamente l'oggetto sul layer BLL prima di eseguire il cambiamento?

risposta

3

Devo lavorare direttamente con il modello dati/entità reale dal mio DAL nel mio livello Presentazione?

Questo va bene per progetti di piccole e medie dimensioni. Ma quando si ha un progetto di grandi dimensioni con più di 5 sviluppatori in cui diversi livelli vengono assegnati a diversi team, il progetto trae beneficio dall'utilizzo di un DTO per separare il livello dati dal livello di presentazione.

Con un DTO nel mezzo, eventuali modifiche del livello di presentazione non influenzerà il livello di dati (e viceversa)

O devo creare un DTO che può essere passato dal livello di presentazione alla livello aziendale quindi convertirlo in un'entità, quindi essere aggiornato nel DB tramite una chiamata ORM. È scritto troppo codice? Suppongo che ciò sia necessario se il livello di presentazione non ha alcun concetto del modello di dati. Se stiamo seguendo questo approccio, dovrei recuperare nuovamente l'oggetto sul layer BLL prima di eseguire il cambiamento?

Per creare una nuova entità, allora questo è il modo usuale per andare (ad esempio "nuovo utente").Per l'aggiornamento di un'entità esistente, non si converte un DTO in un'entità, ma si recupera l'entità esistente, si mappano i nuovi valori e si avvia un aggiornamento ORM.

UpdateUser(UserDto userDto) 
{ 
    // Fetch 
    User user = userRepository.GetById(userDto.ID); 

    // Map 
    user.FirstName = userDTO.FirstName; 
    user.LastName = userDTO.LastName; 

    // ORM Update 
    userRepository.Update(user); 
    userRepository.Commit(); 
} 

Per i progetti di grandi dimensioni con molti sviluppatori, lo svantaggio di scrivere troppo codice viene confrontato minimo per l'enorme vantaggio di disaccoppiamento che fornisce.

Vedi il mio post su Why use a DTO

+1

"Per aggiornare un'entità esistente, non si converte un DTO in un'entità, piuttosto si recupera l'entità esistente, si mappano i nuovi valori" non si scriverà lo stesso codice di mappatura due volte in questo modo? – Reek

1

La mia opinione è che DTO rappresenti i contratti (o i messaggi, se vuoi) che formano la base per l'interazione tra una radice aggregata e il mondo esterno. Sono definiti nel dominio e l'AR deve essere in grado sia di gestire le istanze in arrivo sia di fornire istanze in uscita. (Si noti che nella maggior parte dei casi, le istanze DTO saranno sia forniti da AR o gestita dal AR, ma non entrambi, perché avere uno DTO che scorre in entrambe le direzioni di solito è una violazione di separazione degli interessi.)

Allo stesso tempo, l'AR è responsabile della fornitura della logica aziendale attraverso cui vengono elaborati i dati contenuti nei DTO. Il livello di presentazione (o qualsiasi altro attore che include il livello di accesso ai dati, per quella materia) è libero di inserire qualsiasi Dibattito che vuole in un DTO e richiedere che l'AR lo elabori, e l'AR deve essere in grado di interpretare il contenuto del DTO come incomprensibili e sollevare un'eccezione.

A causa di questo requisito, non è mai opportuno mappare semplicemente un DTO alla controparte Entity.

Il DTO deve sempre essere elaborati attraverso la logica del AR per influenzare cambiamenti nell'entità tale possono portarla allo stato descritto dal DTO.

+0

Vorrei anche aggiungere che se si sta facendo DDD/CQRS, l'aggregato radice non avrebbe mai fornire una DTO, perché quelli sarebbe venuto dal modello di vista. Tuttavia, poiché la domanda è ** non ** su DDD/CQRS, presumo che tu stia utilizzando l'AR per ottenere i dati presentati dal livello di presentazione. – arootbeer

+1

Sono d'accordo con la tua affermazione in grassetto, ma non con la parte relativa alle interfacce DTO. Un DTO non ha un comportamento per definizione e lo scopo di un'interfaccia è di fornire un contratto comportamentale, quindi perché un'interfaccia DTO? Inoltre, le Entità di dominio non accettano DTO non elaborati dal client, il più delle volte passa prima attraverso un livello di Applicazione. I servizi del livello applicazione sanno come chiamare i metodi Entity/AR, passandoli oggetti value o semplici valori primitivi (ma non DTO nel senso "trasferimento dati" del termine). – guillaume31

+0

Suppongo che sto usando una comprensione un po 'specializzata del termine * interfaccia * - Sto pensando al linguaggio C#, in cui la nozione di una "proprietà di sola lettura" può essere esposta a livello di interfaccia. Nel senso più stretto, questo dà al "comportamento" del DTO: "Ho un valore, e tu sei il benvenuto a guardarlo, ma non puoi cambiarlo". Il mio intento era più che le ** interfacce ** permettessero al DTO di essere immutabili al codice ricevente. In ogni caso, la specifica delle * interfacce * nella risposta è irrilevante, quindi la rimuoverò. – arootbeer

15

Qualche considerazione:

  • DTO è un termine sovraccarico, ma come è l'acronimo di Data trasferimento oggetto, la vedo più come una questione puramente tecnica, potenzialmente serializzabile container per ottenere dati da un punto all'altro, di solito su livelli o forse livelli. All'interno di un livello che si occupa di problemi di business, come il livello Dominio in DDD, queste piccole strutture di dati che circolano tendono ad essere nominate Value Objects, perché hanno un significato aziendale e fanno parte del linguaggio Ubiquitous del dominio. Esistono tutti i tipi di sottili differenze tra DTO e oggetti valore, come ad esempio non è necessario confrontare i DTO, mentre il confronto e l'uguaglianza è una preoccupazione importante nei VO (due VO sono uguali se i loro dati incapsulati sono uguali).

  • DDD ha l'accento sull'idea di un ricco modello di dominio. Ciò significa che di solito non si limita a mappare le DTO da uno a uno a entità di dominio, ma si tenta di modellare le azioni di business come metodi rivelatori di intenzioni nelle proprie entità. Per esempio, non si utilizzare setter per modificare un User s' Street, City e ZipCode ma piuttosto chiamare un metodo moveTo(Address newAddress) invece, Address essere un oggetto di valore dichiarato nel livello di dominio.

  • DTO di solito non raggiungono il livello di dominio, ma passare attraverso il filtro di uno strato di applicazione. Può essere controller o servizi applicativi dedicati. Sono gli oggetti del livello Applicazione che sanno come trasformare i DTO che hanno ricevuto dal client, nelle chiamate corrette alle Entità del livello del dominio (di solito i Root aggregati caricati dai repository). Un altro livello di rifinitura superiore è quello di creare tasked-based UIs dove l'utente non invia DTO incentrati sui dati ma Comandi che riflettono il loro obiettivo finale.

Così, la mappatura di DTO to Entities non è davvero il modo DDD di fare le cose, si denota più di un approccio CRUD-oriented.