2012-11-30 10 views
6

Ho un sistema in cui un utente risponde alla domanda in un modulo. Ho oggetti che rappresentano questo modello, ma non sono abbastanza sicuro su come organizzare questi oggetti in termini di DDD.La radice aggregata con gerarchia profonda è appropriata in DDD?

  1. Modulo (ha un proprio elenco di) Sezioni;
  2. Sezione -> (ha il proprio elenco di) Gruppi;
  3. Gruppo -> (ha una propria lista di) Domande;
  4. Domanda -> (può avere una propria lista di sottointerrogazioni) Domande;
  5. Domanda -> (ha il proprio elenco di) Risposte;
  6. Risposta -> (ha il proprio elenco di) Answer_Details;
  7. Answer_Detail -> (potenzialmente ha il proprio elenco di dettagli secondari) Sub_Answer_Details.

Ogni oggetto ha più di 15 proprietà e ciascuna non ha senso senza il relativo genitore. Secondo DDD, credo che l'entità Form dovrebbe essere una radice aggregata e tutti gli altri oggetti dovrebbero essere oggetti valore. Ciò significa che ho bisogno di un repository solo per l'entità Form. In questo caso, FormRepository sarà ingombrato con tutti i tipi di metodi CRUD per oggetti figlio. Il mio ragionamento è corretto in termini di DDD? Va bene che finisco con un aggregato molto ampio? Credo che una tale rappresentazione possa facilmente portare a problemi di prestazioni.

risposta

3

Sì, la gerarchia profonda è valida in DDD.

Va bene che mi ritrovo con un aggregato molto esteso? - se la realtà è così complessa e il tuo modello di dominio è il migliore che riesci a trovare, finirai con una radice aggregata complessa.

Sì, Form deve essere una radice aggregata.

tutti gli altri oggetti devono essere valore oggetti - mal tutti gli altri oggetti devono essere soggetti radice non aggregate (con Id) senza un repository a prenderli. L'oggetto valore non ha un ID e un oggetto di uguaglianza di valori è determinato solo dai suoi valori di attributo, non dall'uguaglianza di Ids (ulteriori informazioni here).

In questo caso FormRepository sarà ingombra di tutti i tipi di metodi CRUD per oggetti figlio - no, un repository dovrebbe contenere solo metodi per quanto riguarda radice aggregata, cioè Get<T> , Save<T> where T : IAggregateRoot, una volta che si ottiene un esempio di una radice di aggregazione, è possibile attraversare tramite attributi e metodi per ottenere ciò che ti serve.Esempio:

var formId = 23; 
var form = _formRepository.Get(formId); 
var firstGroup = form.Sections.First().Group().First(); 

o meglio

var groupIndex = 1; 
var firstGroup = form.GetGroupAt(groupIndex); 

dove

public Group GetGroupAt(int groupIndex) 
{ 
    Sections.First().Group().ElementAt(groupIndex); 
} 

credo che tale rappresentazione può facilmente portare a problemi di prestazioni - se si utilizza CQRS, vuoi essere chiamata un po 'Form metodo di dominio dal gestore di comandi e se si utilizza NHibernate per la persistenza dell'entità, lo farà per impostazione predefinita t utilizzare il caricamento lazy e caricare solo Form dal DB, quindi caricare solo le entità che si toccano realmente, quindi ad esempio Sections.First() caricheranno tutte le sezioni da DB, ma non i gruppi e il resto. Per eseguire una query, devi creare un FormDto (oggetto di trasferimento dati) e altri dtos eventualmente appiattiti per ottenere i dati nel modulo necessario (che potrebbe essere diverso dalla struttura delle entità e l'interfaccia utente potrebbe guidare la struttura dto). Date un'occhiata al mio blog per informazioni per quanto riguarda DDD/CQRS/NHibernate/Repository

+0

Appena letto di recente [Effective Aggregate Design] (https://vaughnvernon.co/?p=139) in cui sono consigliati piccoli aggregati. Potrebbero esserci problemi di prestazioni con un enorme aggregato che contiene una raccolta di entità figlio con migliaia di elementi, perché l'aggiunta di un elemento alla raccolta sta recuperando l'intera raccolta (ad es. Funziona come questa) – xhafan

+0

Corretto il collegamento a [Effective Aggregate Design] (http://dddcommunity.org/library/vernon_2011) – xhafan

+0

Dipende da molti fattori. Ci saranno modifiche simultanee della stessa forma?Se la risposta è sì, non si dovrebbe creare un aggregato cluster più grande. Inoltre, il tuo caso d'uso è molto CRUD quindi dal tuo punto di vista dell'interfaccia utente presumo che tu abbia appena presentato tutti i campi modificabili per l'intero modulo e lo salvi come un intero documento. Tuttavia, se l'interfaccia utente era un po 'più segregata (ad esempio consentendo di modificare un singolo gruppo alla volta, o una singola sezione, ecc., Allora si trarrebbe vantaggio dall'avere più AR). – plalx

4

Anche se una risposta è stata accettata ho pensato che tanto vale aggiungere il mio 2 centesimi:

gerarchie profonde sono (probabilmente) bene ma ricorda che l'idea alla base di un aggregato è di impedirlo. Tendo a pensare di entità in un aggregato lungo le linee di:

"Fa questa entità ha alcun significato senza AR?"

Poiché non ho alcun contesto w.r.t. il tuo modello userò Order/OrderLine. Un OrderLine ha un significato senza lo Order? Posso fare qualcosa (comportamento) con la riga ordine da solo? La risposta ovvia qui è "no".

Ogni modello dovrà essere trattato in base al contesto. Ma la proprietà non significa necessariamente contenimento.

Questi possono essere più facile da vedere quando si lavora con i contesti limitati separati forniti si ha l'BCs correggere :)

Nel tuo caso un Answer può avere alcun significato senza la sua Question. Ma forse un Question può vivere in un QuestionBank BC e una particolare domanda può essere utilizzata sia nel tuo Examination BC che nel tuo Enrollment BC. Tutti questi sono totalmente inventati in modo che dipendano dal tuo contesto.

Quindi, se è il caso che Question può essere un AR, allora le domande che appartengono al tuo Form AR possono essere semplicemente un oggetto valore o anche un semplice oggetto interrogativo.

+0

Grazie per i tuoi 2 centesimi. Non capisco bene cosa intendi con: _Perché è possibile che la domanda sia un AR, allora le domande che appartengono al tuo modulo AR possono semplicemente essere un oggetto valore_. – ddv

+0

Come 'Domanda' essere un AR può essere un oggetto valore. Tutte le AR dovrebbero essere Entità. In realtà nel mio caso tutti gli oggetti non hanno senso senza un proprietario. Non sono accessibili senza contesto modulo. Sezioni e gruppi nel mio caso non hanno altro significato che raggruppare le domande. Per favore, fammi sapere se il tuo approccio sarebbe diverso da quello di @xhafan. Quali oggetti pensi possano essere VO – ddv

+0

Ah, capisco perché la risposta potrebbe non avere senso :) --- scusami per quello. Quello che voglio dire è che se un AR in BC-A è usato in BC-B allora in BC-B puoi usare solo l'ID AR appropriato * o * lo modello come oggetto valore. Il modello dipenderà al 100% dal tuo contesto/comprensione del modello. Quindi non posso dire, per certo, che quello che hai non è corretto. Tuttavia, ho modellato le AR in modo simile in passato e, a ben vedere, so che non era corretto al 100%. Se funziona allora va bene; se ti imbatti in problemi/duplicazioni, vorrai rivedere il modello. –

Problemi correlati