Sembra esserci una confusione tra concetti di progettazione guidati dal dominio, progettazione dell'API e approccio di implementazione.
Concetti di progettazione del dominio
Prima alcune definizioni del libro di riferimento DDD di Evan:
Aggregate: A cluster of associated objects that are treated as a unit for the purpose of data changes. External references are
restricted to one member of the aggregate, designated as the root.
Entity: An object fundamentally defined not by its attributes, but by a thread of continuity and identity.
E tieni presente che si tratta del dominio. Non ci interessa qui come saranno implementate le relazioni tra gli oggetti. Pertanto, da quello che dici:
-
User
e relativo Posts
appartengono allo stesso aggregato e User
è l'entità radice di esso. Questo dice che ogni volta che voglio fare riferimento a Post
, comunque è implementato, devo accedervi tramite User
.
- non è chiaro se
Post
all'interno dell'aggregato sia una entità o un oggetto valore . La differenza riguarda la semantica dell'identità: un post che viene aggiornato (ad esempio la correzione di un errore di battitura) è ancora lo stesso post o sarebbe considerato come un altro post? Personalmente opterei per l'entità, ma fino a te per vedere cosa si adatta meglio al tuo dominio.
Progettazione e ampli API modello di implementazione
Il modello di dominio è indipendente da qualsiasi implementazione specifica. Ma per implementarlo, devi definire:
- Un'API, che definisce in che modo il dominio viene esposto ai livelli dell'applicazione che utilizzano il modello (ad esempio controller e viste).
- Un approccio di implementazione per la gestione degli interni dipendenti dall'implementazione del modello, ad esempio per garantire la persistenza (ad esempio l'uso di una mappatura Object-Relational o l'uso di un database NOSQL).
Il modello di dominio non deve essere una prigione che ti impone di fare ciecamente cose che ostacolano le prestazioni, ma una guida per strutturare meglio il tuo software.
Nel tuo caso specifico, potresti ad esempio utilizzare caricamento lento : la tua API potrebbe dare l'impressione che tutto sia caricato contemporaneamente con User
, ma in realtà, posts
non verrà caricato fino a quando qualcuno non tenterà di accedervi tramite User
(grazie all'incapsulamento).
Ma potresti anche definire un'API che sembra dare accesso diretto alle entità nell'aggregato, ma che impone l'accesso a Post
per passare a User
, in modo da avere l'opportunità di salvaguardare la coerenza di gli oggetti correlati.
Potresti anche, come suggerisci tu stesso, creare diversi tipi di oggetti User
nell'applicazione per determinare cosa deve essere caricato e cosa potrebbe essere modificato. Ma poi è un modello di implementazione e non più il modello di dominio concettuale più.