Il modello di dati deve essere identico al modello di dominio per scopi di mappatura?

2

Dire che ho un modello di dati, che assomiglia a questo:

public class DataCustomer
{ 
    public virtual System.DateTime CreatedTime { get; set; }
    public virtual Guid Id { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string Surname { get; set; }
    public virtual string FaxNumber{ get; set; }
    public virtual System.DateTime DateOfBirth { get; set; }
    public virtual String Gender { get; set; }
    public virtual string UserID { get; set; }
    public virtual List<Offers> Offers { get; set; }
}

Questa classe è mappata a NHibernate. Ora dì che ho un modello di dominio come questo:

public class DomainCustomer
{ 
    private virtual Guid Id { get; set; }
    private virtual String Gender { get; set; }
    private virtual DateTime DateOfBirth { get; set; }
    public virtual List<Offers> Offers { get; set; }

    public DomainCustomer(Guid id, string gender, DateTime dateOfBirth)
    {
          Id=id;
          Gender=gender;
          DateOfBirth=dateOfBirth;
    }

    public void AssignOffers(IOfferCalculator offerCalculator, IList<Offers> offers)
    {
          //Assign the offers here
    }

}

Si noti che il modello di dati ha un aspetto diverso rispetto al modello di dominio. Credo che questa sia una pratica normale, tuttavia ogni esempio che guardo online sembra mostrare che il modello di dati è lo stesso del modello di dominio.

Opzione 1

Il vantaggio di essere identici è che la mappatura tra il modello di dominio e il modello di dati è molto semplice, cioè puoi farlo con AutoMapper:

DataCustomer dataCustomer = AutoMapper.Mapper.Map<DataCustomer>(domainCustomer);

Opzione 2

Il vantaggio di essere diversi è che ci sono meno dati tra il modello di dati e il modello di dominio e viceversa. Inoltre, penso che ciò rende leggermente più chiaro, ad esempio, un utente / lettore della mia classe sa quali campi sono necessari per il modello di dominio. Con questo approccio; Vorrei solo mappare i membri che hanno cambiato le offerte:

customerData.Offers = AutoMapper.Mapper.Map<string>(customerDomain.Offers);

decisione

Entrambe le opzioni utilizzano una fabbrica durante il mapping tra CustomerData e CustomerDomain. La domanda riguarda la mappatura tra CustomerDomain e CustomerData utilizzando AutoMapper.

Quale opzione è più probabile se seguo il principio del minimo stupore?

    
posta w0051977 09.02.2018 - 10:54
fonte

4 risposte

4

Per semplicità, supponiamo che il tuo "modello di dati" rifletta il modello di persistenza sottostante, probabilmente un modello relazionale dietro di esso. Quindi dipende pesantemente dalle dimensioni e dalla struttura del sistema generale quanto il modello di dati sarà diverso dal modello di dominio:

  • nei piccoli sistemi, ci sarà spesso solo un'applicazione principale. Si inizia con la creazione di un modello di dominio di piccole dimensioni e il modello di dati verrà derivato da esso, unicamente allo scopo di mantenere il modello di dominio. In un tale sistema, è improbabile che ci sia differenza tra i modelli. In effetti, generarne uno dall'altro, o codice piastra caldaia per tutti loro da una meta sorgente comune ha senso.

  • i sistemi più grandi possono essere strutturati in un modo in cui un database comune in background offre un modello di dati più ampio condiviso da diverse applicazioni o "contesti limitati", ognuno dei quali accede a una parte diversa del sistema, magari da un punto diverso di vista, ma non completamente disgiunto. Le regole di normalizzazione e l'obiettivo di memorizzare ciascuna parte di informazioni in un unico posto possono quindi portare a differenze tra il modello di dati e un modello di dominio.

Si noti che questa è ancora una semplificazione, ci sono molti più scenari possibili, come i sistemi più grandi che utilizzano un'architettura microservice, dove ogni servizio è piccolo e ha un proprio modello di persistenza, o sistemi più grandi con un enorme strato di modello di dominio condiviso, dove il modello di dominio e il modello di dati sono garantiti per corrispondere l'uno all'altro dai generatori. Altri scenari possono avere (1) un modello di dominio, (2) un modello di dati nel codice client e (3) un modello di database e tutti e tre differiscono in qualche modo.

Quindi, dopo questa lunga introduzione, cosa sto cercando di dire? Bene, il mio punto è: se il modello di dati e il modello di dominio devono essere identici non è nulla che è dettato dalla strategia di mappatura .

È proprio il contrario: l'architettura generale del sistema ti spiega come sono strutturati i modelli e quindi scegli una strategia di mappatura adatta. Ovviamente, dove sei libero di fare scelte nel design, dovresti evitare di introdurre differenze non necessarie tra i modelli, purché non ci sia un vero motivo per farlo.

Ad esempio, i nomi e i tipi per gli attributi corrispondenti devono essere identici o seguire rigorose regole di mappatura. Ciò può portare a una situazione in cui la mappatura di tutti gli attributi di una classe porta a un codice più semplice rispetto a mappare solo il sottoinsieme degli attributi di cui il tuo programma ha bisogno oggi. In questo caso, consiglierei di iniziare con tutti gli attributi e ottimizzare nel caso in cui noti che questo è un collo di bottiglia reale misurabile.

    
risposta data 09.02.2018 - 14:12
fonte
6

Prima di tutto, avere il tuo modello di dominio diverso dai tuoi dati di persistenza è normale. Se prendi lo schema esagonale tradizionale, puoi vedere che la persistenza viene raggiunta tramite un "adattatore".

Quindi, scegliere tra le opzioni. Credo che la mappatura tra entrambi dovrebbe essere all'interno di un repository (orientato alla persistenza), piuttosto che in una fabbrica. Sembra una piccola differenza di denominazione, ma aiuta a chiarire che un repository può fare molto di più: ad esempio, quando si salva DataCustomer , è possibile che si desideri eseguire il salvataggio a cascata su molti altri modelli di dati.

Infine, quel repository può chiamare Automapper o usare qualsiasi altro meccanismo. Ciò che è veramente importante alla fine è che gli aggregati costruiti hanno rispettato i loro invarianti (tutti i campi obbligatori sono compilati ...). Da quel punto di punto, non vedo proprio la differenza tra i 2 approcci.

In breve: dovresti preoccuparti della qualità del tuo modello di dominio, non dei mezzi tecnici per costruirlo. Il livello del dominio è più importante del livello infrastruttura.

    
risposta data 09.02.2018 - 11:30
fonte
1

Un modello di dominio e il modello di dati hanno una visione diversa del mondo e dovrebbero essere espressi nel codice.

Il modello di dominio deve essere modellato in modo che sia allineato alla vista aziendale dell'applicazione mentre il modello di dati tratta interamente la manipolazione del modello di dominio in modo che sia facile da essere utilizzato da altri per una vista specifica / motivi relativi all'azione (ad esempio API REST, pagina Web o app moduli ...)

    
risposta data 20.02.2018 - 18:18
fonte
0

Non c'è motivo per cui deve mantenerli uguali, anche se è desiderabile .

Immaginate di memorizzare le informazioni in una serie di stringhe. Il tuo modello di dati sarebbe completamente diverso dal tuo modello di dominio.

L'imaging del tuo modello dati non è tuo (stai utilizzando un'API di terze parti). La tua logica aziendale potrebbe essere diversa dalla logica aziendale di quella terza parte.

La regola generale è la seguente: devi mantenere i tuoi modelli di dominio il più vicino possibile alle tue esigenze.

    
risposta data 11.02.2018 - 12:42
fonte

Leggi altre domande sui tag