Devo utilizzare una radice aggregata durante la progettazione del mio repository?

8

Ho un'entità chiamata Master che è composta da un numero di entità Slave.

Ci può essere un solo Master nel mio database e voglio interrogare i repository per ottenere lo Slave per un dato ID.

Inizialmente ho creato un SlaveRepository e l'ho interrogato tramite id. Sembra a posto e funziona e altri sviluppatori potrebbero usare il mio repository.

Poi ho pensato alle radici aggregate e ho creato un MasterRepository e ho restituito il Master e poi ho fatto un ciclo su quello per ottenere l'entità slave richiesta. Il problema che ho sentito qui è una volta che espongo questo ad altri sviluppatori che dovrebbero fare lo stesso, quindi ho un metodo sul MasterRepository chiamato GetSlaveByID (stringa id) e quindi posso ottenere direttamente lo slave (nasconde la funzionalità del loop ).

Ora, il mio repository dovrebbe restituire uno Slave anche se è chiamato MasterRepository? E ancora più importante qual è la strada giusta da percorrere?

Sono nelle prime fasi del tentativo di applicare DDD e TDD quindi ci sono probabilmente molte cose a cui devo pensare prima di decidere quale sia il modo corretto che immagino.

    
posta JD01 10.12.2011 - 14:32
fonte

2 risposte

9

Secondo il metodo di Eric Evans di Domain Driven Design, dovresti evitare i repository per le root non aggregate.

Dichiara chiaramente:

Only Aggregate Roots can be obtained directly with database queries. Everything else must be done through traversal.

Ma significa anche che il repository per la root deve soddisfare tutti i requisiti. Se hai bisogno dell'accesso diretto a parti dell'aggregato, è responsabile di farlo un oggetto radice aggregato o il suo repository.

Quindi è perfettamente bene avere metodi come i seguenti in un repository di aggregati di root:

Slave GetSlave(string id)

Ma questa firma è un po 'pericolosa, poiché le identità dei bambini nel DDD hanno senso solo nel contesto di un oggetto radice reale e sono poco profonde senza la radice.

Questo ci porta a un approccio migliore e più simile a DDD per un'implementazione in un repository:

Slave GetSlaveOfMaster(Master master, string slaveId)
// or
Slave GetSlaveOfMaster(Identity masterId, Identity slaveId)

Ma probabilmente non avrei nemmeno questo metodo sul repository ma sull'entità master stessa per accedere rapidamente agli schiavi. Forse anche esposto come una tabella. Questo è l'approccio più pulito che riesco a pensare.

//within the Master entity
Slave GetSlave(Identity slaveId);

Resisti, questa non è la fine della storia. Se hai bisogno di recuperare gli schiavi senza la conoscenza del master, allora dovresti pensare ai tuoi aggregati e al tuo modello di oggetti. Forse hai bisogno di un secondo aggregato dove lo slave è una radice e quindi dovresti avere un repository personalizzato per loro. Lo slave non è quindi solo un figlio del master, ma una gerarchia separata che probabilmente contiene anche un riferimento a un master. È importante sapere se un oggetto slave può esistere senza un master. Se è possibile, allora un aggregato separato è probabilmente la strada da percorrere.

    
risposta data 10.12.2011 - 16:23
fonte
1

In generale, all'interno del limite aggregato dovrebbe esserci un solo repository. E - come ha detto Falcon - potresti finire con due aggregati separati, master e slave.

Tuttavia sembra che l'obiettivo principale della tua domanda sia il recupero dei dati, mentre nel DDD dovrebbe essere il comportamento. I confini aggregati sono una conseguenza dei vincoli imposti dal comportamento (le cose che cambiano insieme e gli invarianti da applicare), la struttura interna dell'aggregato è una conseguenza di tale scelta.

Ad esempio, se si raggruppano le cose correttamente in base alla necessità di cambiare insieme, non è necessario chiamare un repository esterno. La maggior parte dei casi, i dati necessari per un'operazione commerciale nell'aggregato dovrebbero già essere all'interno dei confini aggregati, la necessità di accedere a aggregati diversi è probabilmente l'odore di un confine incoerente.

    
risposta data 11.12.2011 - 12:45
fonte

Leggi altre domande sui tag