Composizione di oggetti Data Transfer

3

Diciamo che voglio creare un negozio / sistema di ordini. Avrò un DTO Order a cui mapperò i dati di una richiesta e i risultati del database. L'oggetto consisterà in un numero d'ordine, un numero cliente e un elenco di articoli.

Il numero dell'ordine è piuttosto semplice, userò semplicemente un int per memorizzare il numero. Ma per quanto riguarda il cliente? Avrò anche un DTO Customer in modo da poterlo utilizzare all'interno del DTO Order invece di salvare il numero cliente come int.

Nel mio caso il numero cliente è composto da un negozio_no (il negozio in cui è registrato il cliente) e da un cliente_no (numero interno del cliente).

Per me sembra essere più pulito avere una struttura simile a questa:

Order {
 int order_no;
 Customer cust;
}

Customer {
 int store_no;
 int cust_no;
}

invece di questo:

Order {
 int order_no;
 int store_no;
 int cust_no;
}

Customer {
 int store_no;
 int cust_no;
}

Il mio problema: Il Customer DTO avrà molte più informazioni rispetto al solo numero cliente. Come un nome, cognome, indirizzo, nome utente, alcune bandiere e così via. Cose a cui non mi importa quando voglio salvare un ordine con order_no 123 per il cliente con store_no 12 cust_no 543.

Quindi, in questo caso, utilizzare il Customer DTO all'interno del Order DTO sembra essere "troppo".

Lo stesso vale per gli articoli.

Esistono buone pratiche su come creare tali DTO? Incapsulare DTO o ripetere le stesse informazioni in diversi DTO?

    
posta das Keks 30.05.2016 - 15:10
fonte

2 risposte

2

My problem: The Customer DTO will have a lot more information than just the customer number. Like a first name, last name, address, user name, some flags and so on. Things I don't care about when I just want to save an order with order_no 123 for the customer with store_no 12 cust_no 543.

Lo scopo di un oggetto di trasferimento dati è di rappresentare i dati da trasferire a un altro processo, ad es. dal tuo back-end a un front-end web. Se l'informazione che si sta trasferendo ha una struttura nidificata, ha senso usare anche un tipo annidato per il DTO. Tuttavia, il DTO non deve includere dati non necessari che non stai effettivamente utilizzando: è fuorviante.

Un DTO non è assolutamente uguale al modello di dominio. Il tuo modello descrive entità come Customer o Order con tutte le proprietà rilevanti per il tuo dominio problematico. Ciò include la corretta modellazione della relazione tra un Ordine e un Cliente. Non è inusuale finire con un complesso oggetto grafico che descrive tutte queste relazioni (e in modo equivalente: molte chiavi esterne in un database relazionale).

Mi sembra che il tuo Customer "DTO" sia in realtà un modello di dominio accurato, non solo un DTO. Pertanto, sarebbe errato per un Order includere un'istanza Customer completa, se tutto ciò che viene trasferito è in realtà solo un ID. Supponendo che tu stia trasferendo questi dati come JSON, guarderei semplicemente il JSON e ricavo i miei DTO da quello:

{
  "order_no": 1234,
  "store_no": 1234,
  "cust_no": 1234
}

→ meglio rappresentato come DTO singolo e piatto.

{
  "order_no": 1234,
  "customer": { "cust_no": 1234, "store_no": 1234 }
}

→ probabilmente un diverso Order e Customer type.

Un altro approccio possibile prevede diversi DTO per diversi livelli di dettaglio, ad es. un cliente può essere rappresentato come cliente completo con informazioni complete sul profilo o solo come breve sommario del cliente con solo le informazioni essenziali, o anche solo l'ID. Ciò aggiunge molta complessità poiché la stessa entità può essere rappresentata da più tipi di DTO, ma ti impedisce di trasferire dati non necessari. Ciò richiede una decisione di design

    
risposta data 30.05.2016 - 15:40
fonte
0

Trovo che sia il migliore se il tuo DTO corrisponde alla tua struttura dati di back-end.

In questo caso, se si utilizza un db relazionale, presumibilmente il proprio back-end può recuperare il proprio cliente e il numero di negozio associato tramite l'ID cliente. Pertanto è possibile strutturare il DTO dell'ordine in questo modo:

class Order
{
    int order_no;
    int customer_no;
    ...other order info
}

e Cliente:

class Customer
{
    int customer_no;
    int store_no;
    ..... extra customer info
}

Quale corrisponderebbe alle colonne della tabella e alle loro relazioni.

Se tuttavia stai usando un approccio no-sql, dovrebbe probabilmente inviare l'intero oggetto cliente con l'ordine, incluso il nome del cliente, l'indirizzo ecc. poiché il back-end tratterà l'ordine come singola entità con dati annessi, e avrà bisogno dei dettagli del cliente per soddisfare l'ordine.

vale a dire:

class Order
{
    int order_no;
    ...other order details
    Customer customer
    {
        int customer_no;
        ....name address etc
        Store store
        {
            int store_no;
            ....other store details
        }
    }
}
    
risposta data 30.05.2016 - 16:20
fonte

Leggi altre domande sui tag