32

Sto cercando di imparare la progettazione basata sul dominio (DDD) e penso di aver avuto l'idea di base. Ma c'è qualcosa che mi confonde.DDD - Modello di persistenza e modello di dominio

In DDD, il modello di persistenza e il modello di dominio sono cose diverse? Voglio dire, progettiamo il nostro dominio e le nostre classi tenendo conto solo delle preoccupazioni relative al dominio; va bene. Ma dopo, quando stiamo costruendo i nostri repository o qualsiasi altro sistema di persistenza dei dati, dovremmo creare un'altra rappresentazione del nostro modello da usare nel livello di persistenza?

Pensavo che il nostro modello di dominio sia utilizzato anche in persistenza, il che significa che i nostri repository restituiscono i nostri oggetti dominio dalle query. Ma oggi, ho letto questo post, e sono un po 'confuso:

Just Stop It! The Domain Model Is Not The Persistence Model

Se questo è vero quello che sarebbe il vantaggio di avere oggetti persistenza separato da oggetti di dominio?

+2

Ecco un post che ho scritto su questo argomento esatto: http://enterprisecraftsmanship.com/2016/04/05/having-the-domain-model-separate-from-the-persistence-model/ – Vladimir

risposta

41

Basti pensare in questo modo, il modello di dominio dovrebbe dipendere dal nulla e non disporre di alcun codice di infrastruttura al suo interno. Il modello di dominio non dovrebbe essere serializzabile o ereditare da alcuni oggetti ORM o anche condividerli. Questi sono tutti problemi di infrastruttura e dovrebbero essere definiti separatamente dal modello di dominio.

Ma, questo è se stai cercando un DDD puro e il tuo progetto valuta scalabilità e prestazioni rispetto alla velocità dello sviluppo iniziale. Molte volte, mescolare i problemi infrastrutturali con il tuo "modello di dominio" può aiutarti a raggiungere grandi progressi in termini di velocità al costo della scalabilità. Il punto è che è necessario chiedersi: "I benefici del DDD puro valgono il costo della velocità di sviluppo?". Se la tua risposta è sì, allora ecco la risposta alla tua domanda.

Iniziamo con un esempio in cui l'applicazione inizia con un modello di dominio e, nel caso in cui le tabelle nel database corrispondano esattamente al modello di dominio. Ora, l'applicazione cresce a passi da gigante e si iniziano a riscontrare problemi di prestazioni durante l'interrogazione del database. Hai applicato alcuni indici ben ponderati, ma le tue tabelle stanno crescendo così rapidamente che sembra che tu possa aver bisogno di de-normalizzare il tuo database solo per tenere il passo.Quindi, con l'aiuto di un dba, vieni con un nuovo design del database che gestirà le tue esigenze di prestazioni, ma ora le tabelle sono molto diverse da come erano prima e ora i pezzi delle entità di dominio sono distribuiti su più tabelle piuttosto che è una tabella per ogni entità.

Questo è solo un esempio, ma dimostra perché il modello di dominio deve essere separato dal modello di persistenza. In questo esempio, non si desidera suddividere le classi del modello di dominio in modo che corrispondano alle modifiche apportate alla progettazione del modello di persistenza e modificare sostanzialmente il significato del modello di dominio. Invece, si desidera modificare la mappatura tra il nuovo modello di persistenza e il modello di dominio.

Ci sono diversi vantaggi nel tenere separati questi progetti come scalabilità, prestazioni e tempi di reazione ai cambiamenti db di emergenza, ma è necessario valutarli rispetto al costo e alla velocità dello sviluppo iniziale. In generale, i progetti che otterranno il massimo beneficio da questo livello di separazione sono le applicazioni aziendali su larga scala.

UPDATE per i commentatori

Nel mondo dello sviluppo del software, v'è il numero ennesimo di possibili soluzioni. Per questo motivo esiste una relazione inversa indiretta tra flessibilità e velocità iniziale di sviluppo. Come semplice esempio, potrei inserire una logica del codice in una classe o scrivere una classe che consenta il passaggio di regole di logica dinamica. L'opzione precedente avrebbe una maggiore velocità di sviluppo, ma al prezzo di un minore grado di flessibilità. Quest'ultima opzione avrebbe un più alto grado di flessibilità, ma al costo di una minore velocità di sviluppo. Questo è vero in ogni linguaggio di programmazione perché c'è sempre un numero di soluzioni possibili.

Sono disponibili molti strumenti che consentono di aumentare la velocità iniziale di sviluppo e la flessibilità. Ad esempio, uno strumento ORM può aumentare la velocità di sviluppo del proprio codice di accesso al database, offrendo allo stesso tempo la flessibilità di scegliere qualsiasi implementazione di database specifica supportata dall'ORM. Dal tuo punto di vista, questo è un guadagno netto in termini di tempo e flessibilità, meno il costo dello strumento (alcuni dei quali sono gratuiti) che potrebbero o meno valere per te in base al costo del tempo di sviluppo relativo al valore del esigenza aziendale.

Ma, per questa conversazione negli stili di codifica, che è essenzialmente ciò che Domain Driven Design è, è necessario tenere conto del tempo impiegato per scrivere quello strumento che si sta utilizzando. Se si dovesse scrivere lo strumento ORM o addirittura scrivere la logica di accesso al database in modo tale da supportare tutte le implementazioni fornite da tale strumento, ci sarebbe voluto molto più tempo rispetto a quando si stesse semplicemente codificando l'implementazione specifica che si pianifica sull'uso.

In breve, gli strumenti possono aiutare a compensare il proprio tempo di produzione e il prezzo della flessibilità, spesso distribuendo il costo di quel tempo a chiunque acquisti lo strumento. Tuttavia, qualsiasi codice che includa il codice che utilizza uno strumento rimarrà influenzato dalla relazione velocità/flessibilità. In questo modo, Domain Driven Design consente una maggiore flessibilità rispetto a quando si intreccia la logica aziendale, l'accesso al database, l'accesso al servizio e il codice dell'interfaccia tutti insieme, ma al costo del tempo necessario per la produzione. Domain Driven Design offre applicazioni di livello aziendale migliori rispetto alle piccole applicazioni perché le applicazioni di livello aziendale tendono ad avere un costo maggiore per il tempo di sviluppo iniziale in relazione al valore aziendale e poiché sono più complesse, sono anche soggette a modifiche che richiedono maggiore flessibilità in un costo ridotto nel tempo.

+1

è un'ottima risposta, ma continui a ribadire che dobbiamo "scegliere" - vorrei che chiarissi perché pensi che non possiamo avere la nostra torta e mangiarla anche tu? Mi sembra che se esistessero strumenti migliori per facilitare questo tipo di sviluppo, la velocità dello sviluppo iniziale non dovrebbe essere un fattore? Gli strumenti non sono ancora lì? –

+1

Mi piacerebbe vedere un commento anche su questo. – Seralize

+0

Aggiunto aggiornamento per i commentatori per rispondere alle tue domande. –

9

In DDD, il modello di persistenza e il modello di dominio sono cose diverse?

Sì, ma ciò non implica necessariamente un diverso insieme di classi per rappresentare esplicitamente il modello di persistenza.

Se si utilizza un database relazionale per la persistenza, un ORM come NHibernate può occuparsi di rappresentare il modello di persistenza tramite mapping alle classi di dominio. In questo caso non ci sono classi del modello di persistenza esplicite. Il successo di questo approccio dipende dalle capacità di mappatura dell'ORM. NHibernate, ad esempio, può supportare una classe di mapping intermedia tramite component mappings. Ciò consente l'uso di una classe di modello di persistenza esplicita quando si presenta la necessità.

Se si utilizza un database di documenti per la persistenza, in genere è ancora meno necessario un modello di persistenza poiché il modello di dominio deve essere serializzabile solo per poter essere mantenuto.

Pertanto, utilizzare una classe del modello di persistenza esplicita quando esiste una mappatura complessa che non può essere raggiunta con i mapping ORM al modello di dominio. La differenza tra il modello di dominio e il modello di persistenza rimane indipendentemente dall'implementazione.

+0

Hmm, quindi I posso usare le stesse classi finché riesco a gestire la persistenza nel modo giusto. Quando non è abbastanza, posso ripensare e aggiungere alcune nuove classi invece di classi di dominio per la persistenza. Ho capito bene? – ayk

+0

Sì, e le classi specifiche della persistenza possono venire in una varietà di sapori. Possono essere un semplice DTO tra il database e il dominio oppure possono far parte di un'infrastruttura di mappatura esistente come NHibernate. – eulerfx

+0

Penso, ora è chiaro, grazie per la vostra attenzione e il vostro aiuto. – ayk

4

In DDD, il modello di persistenza e il modello di dominio sono cose diverse?

In DDD si ha il modello dominio e la repository. Questo è tutto. Se all'interno del repository manterrai il modello del tuo dominio direttamente o lo convertirai in un modello di persistenza, prima che persista dipenda da te! È una questione di design, il tuo design.

Come altri utenti hanno indicato che ciascuna opzione ha i suoi pro e contro. Date un'occhiata a questo answer dove dettaglio alcuni di loro.

+1

Ho letto molti articoli su DDD ma la tua breve descrizione è la migliore di tutti. Grazie. – user2980426

Problemi correlati