2009-09-06 17 views
12

Sto prendendo in considerazione l'utilizzo di DTO anziché passare attorno ai miei oggetti dominio. Ho letto diversi post qui e altrove, e capisco che ci sono diversi approcci per ottenere questo risultato.DTO: best practice

Se ho solo circa 10 classi di domini in tutto e considerando che voglio utilizzare DTO anziché oggetti di dominio per il consumo nelle mie viste (front end WPF), qual è l'approccio consigliato. Penso che l'uso di strumenti come l'automapper, ecc., Possa essere eccessivo per la mia situazione. Quindi sto pensando di scrivere la mia classe mapper personalizzata che avrà metodi per convertire un tipo di dominio in un tipo DTO.

Qual è il modo migliore per farlo, ci sono esempi per iniziare a farlo?

Seconda domanda: quando si scrivono quei metodi che creeranno DTO, come faccio a configurare tutti i dati, specialmente quando il tipo di dominio ha riferimenti ad altri oggetti di dominio? Scrivo proprietà equivalenti nel DTO per mappare a quei tipi di refernece nella classe di dominio? Per favore, chiedi se non ho messo la mia seconda domanda in parole appropriate. Ma penso che tu capisca quello che sto cercando di chiedere.

Thrid question: durante la scrittura di DTO, dovrei scrivere più DTO, ciascuno contenente dati parziali per un dato modello di dominio, in modo che ognuno di essi possa essere utilizzato per soddisfare uno specifico requisito di visualizzazione, o se il DTO ha tutto il dati che ci sono nella classe del modello corrispondente.

+0

Siate pronti a anche scrivere più oggetti di trasferimento dati specifici per specifici metodi di servizio, non solo per specifici domini M odelli. – Lightman

risposta

0

Presumo che gli oggetti del modello di dominio abbiano un ID di chiave primaria che potrebbe corrispondere agli ID del database o dello store da cui provengono.

Se quanto sopra è vero, il DTO supererà il tipo di riferimento ad altri DTO come fanno gli oggetti dominio, sotto forma di ID di chiave esterna. Quindi una relazione OrderLine.OrderHeader sull'oggetto dominio sarà OrderLine.OrderHeaderId cin DTO.

Spero che questo aiuti.

Posso chiederti perché hai scelto di utilizzare DTO anziché i tuoi oggetti di dominio avanzato nella vista?

+1

I DTO possono avere proprietà ID in essi? - Ovvero OrderlineID nel tuo campione. Pensavo che le DTO fossero oggetti di dati completamente autonomi che non avevano alcun riferimento al database e ad altre dipendenze esterne. Per quanto riguarda il motivo per cui i DTO, il mio progetto si trasformerà in un grande sistema in futuro, e voglio assicurarmi che lo costruisca ora per aderire alla possibilità di esporre i dati su richieste di servizi web, ecc. In futuro. Beeter seguirà le buone pratiche dal giorno 0 suppongo. Hai qualche idea per la mia terza domanda (che ho aggiunto solo pochi minuti indietro). –

3

Sono un po 'come usare DTO in un progetto. Tendo a rendere i DTO solo per mostrare i dati di cui ho bisogno per una vista specifica. Prendo tutti i dati mostrati nella vista nella mia classe di accesso ai dati. Ad esempio, io possa avere un oggetto Ordine che fa riferimento a un oggetto Cliente:

public class Client{ 
    public int Id{get;set;} 
    public string Name{get;set;} 
} 

public class Order{ 
    public int OrderID{get;set;} 
    public Client client{get;set;} 
    public double Total{get;set;} 
    public IEnumerable<OrderLine> lines {get;set;} 
} 

Poi nel mio OrderListDTO io possa avere qualcosa di simile:

public class OrderListDTO{ 
    public int OrderId{get;set;} 
    public string ClientName{get;set;} 
    ... 
} 

Quali sono i campi che voglio mostrare a mio avviso . Prendo tutti questi campi nel mio codice di accesso al database, quindi non devo preoccuparmi delle associazioni delle entità nella mia vista o nel codice del controller.

+0

Come gestite la proprietà "linee" negli oggetti DTO? Rendi ordinato OrderListDTO o carichi la collezione "lines" come? –

+0

Dipende dal contesto. Se ho bisogno delle linee nella vista, le carico; se no, io no. A volte ho una proprietà LineCount sul mio OrderListDTO e faccio LineCount = order.lines.Count(), o mostro un totale: LineSum = order.lines.Sum (t => t.Quantity) ... –

5

Ho letto alcuni post in merito ai DTO e mi sembra che molte persone li identifichino a ciò che considererei un ViewModel. Un DTO è proprio questo, oggetto di trasferimento dati: è ciò che viene trasmesso. Quindi ho un sito Web e servizi, solo i servizi avranno accesso a oggetti dominio/entità reali e restituiranno DTO. Questi possono mappare 1: 1, ma si consideri che il DTO può essere popolato da un'altra chiamata di servizio, una query di database, la lettura di una configurazione, qualunque sia.

Successivamente, il sito Web può quindi acquisire tali DTO e aggiungerli a un ViewModel o convertirli in uno. Quel ViewModel può contenere molti diversi tipi di DTO.Un semplice esempio potrebbe essere un task manager: ViewModel contiene sia l'oggetto task che si sta modificando, sia un gruppo di oggetti Dto.User a cui è possibile assegnare l'attività.

Ricordare che i servizi che restituiscono DTO possono essere utilizzati sia da un sito Web, sia da un'applicazione per tablet o telefono. Queste applicazioni avrebbero viste diverse per sfruttare i loro display e quindi i ViewModels sarebbero diversi, ma i DTO rimarrebbero gli stessi.

Ad ogni modo, adoro questi tipi di discussioni, quindi chiunque mi faccia sapere cosa ne pensi.

Matt

+0

Solo per chiarire un DTO non è un ViewModel. Non è un DisplayModel è un agnostico TransferModel dell'interfaccia utente. Ancor più quando si eseguono i servizi REST trasferendo DTO, non dovrebbero sapere nulla della struttura dell'interfaccia utente. – Elisabeth

1

vengo a proiettare con spring-jdbc e non ci sono utilizzati DAO strato. Alcune volte le entità esistenti non coprono tutti i possibili dati dal DB. Quindi inizio a utilizzare DTO.

Applicando '70 regola programmazione strutturata Ho messo tutti in DTOs pacchetto separato:

package com.evil.dao;  // DAO interfaces for IOC. 
package com.evil.dao.impl; // DAO implementation classes. 
package com.evil.dao.dto; // DTOs 

Ora mi ripensare e decidere di mettere tutti DTO come classi interne sulle interfacce DAO per il risultato-set che non hanno il riutilizzo. Così l'interfaccia DAO assomigliare:

interface StatisticDao { 
    class StatisticDto { 
     int count; 
     double amount; 
     String type; 

     public static void extract(ResultSet rs, StatisticDto dto) { ... } 
    } 

    List<StatisticDto> getStatistic(Criteria criteria); 
} 


class StatisticDaoImpl implements StatisticDao { 
    List<StatisticDto> getStatistic(Criteria criteria) { 
     ... 
     RowCallbackHandler callback = new RowCallbackHandler() { 
      @Override 
      public void processRow(ResultSet rs) throws SQLException { 
       StatisticDao.StatisticDto.extract(rs, dto); 
       // make action on dto 
      } 
     } 
     namedTemplate.query(query, queryParams, callback); 
    } 
} 

Penso che tenendo relativi dati insieme (personalizzato DTO con interfaccia DAO) rendere il codice migliore per i PageUp/PageDown.

0

modo migliore per sviluppare DTOS

Il modo per iniziare DTOS in via di sviluppo è quello di capire che il loro unico scopo è quello di trasferire sottoinsieme dei dati dei vostri entità di business ai clienti diversi (potrebbe essere interfaccia utente, o un servizio esterno). Data questa comprensione è possibile creare pacchetti separati per ogni cliente ... e scrivere le tue classi DTO. Per la mappatura è possibile scrivere il proprio mapper che definisce le interfacce da passare a un factory che crea oggetti DTO in base ai dati estratti dall'entità per cui viene creato il DTO. Puoi anche definire annotazioni da inserire nei tuoi campi di entità, ma personalmente, dato il numero di annotazioni utilizzate, preferirei l'interfaccia. La cosa principale da notare sui DTO è che sono anche classi e i dati tra le DTO dovrebbero essere riutilizzati, in altre parole mentre potrebbe sembrare allettante creare DTO per ogni caso d'uso, provare a riutilizzare i DTO esistenti per minimizzare questo.

Per iniziare

sul reperimento iniziato come detto in precedenza l'unico scopo del DTO è quello di dare al cliente i dati di cui ha bisogno .... in modo da tenere a mente si può solo impostare i dati nel dto utilizzando setter ... o definire una fabbrica che crea un DTO da un'entità basata su un'interfaccia .....

per quanto riguarda la terza domanda, fare come è richiesto dal cliente :)