¿Debo usar una raíz agregada al diseñar mi repositorio?

8

Tengo una entidad llamada Master que está compuesta por varias entidades Slave.

Solo puede haber un Maestro en mi base de datos y quiero consultar repositorios para obtener el Esclavo para una identificación determinada.

Inicialmente creé un SlaveRepository y lo pregunté por id. Eso parece estar bien y funciona, y otros desarrolladores podrían usar mi repositorio.

Luego pensé en las raíces agregadas y creé un MasterRepository y devolví el Master y luego hice un ciclo para obtener la entidad Slave requerida. El problema que sentí aquí es que una vez que expongo esto a otros desarrolladores tendrían que hacer lo mismo, así que tuve un método en el MasterRepository llamado GetSlaveByID (id de cadena) y luego pude obtener el Slave directamente (oculta la funcionalidad del bucle )

Ahora, ¿debería mi repositorio devolver un Esclavo aunque se llame MasterRepository? Y lo más importante, ¿cuál es el camino correcto?

Estoy en las primeras etapas de tratar de aplicar DDD y TDD, por lo que probablemente hay muchas cosas en las que debo pensar antes de decidir cuál es la forma correcta, supongo.

JD01
fuente

Respuestas:

9

De acuerdo con la forma de diseño controlado por dominios de Eric Evans, debe evitar repositorios para raíces no agregadas.

Él dice claramente:

Solo se pueden obtener raíces agregadas directamente con las consultas de la base de datos. Todo lo demás debe hacerse a través del recorrido.

Pero también significa que el repositorio de la raíz debe cumplir todos los requisitos. Si necesita acceso directo a partes del agregado, entonces un objeto raíz agregado o su repositorio es responsable de hacerlo.

Por lo tanto, está perfectamente bien tener métodos como los siguientes en un repositorio raíz agregado:

Slave GetSlave(string id)

Pero esta firma es un poco peligrosa, ya que las identidades de los niños en DDD solo tienen sentido en el contexto de un objeto raíz real y son superficiales sin la raíz.

Esto nos lleva a un enfoque mejor y más DDD para una implementación en un repositorio:

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

Pero probablemente ni siquiera tendría este método en el repositorio sino en la entidad maestra para acceder rápidamente a los esclavos. Posiblemente incluso expuesto como una tabla hash. Ese es el enfoque más limpio que se me ocurre.

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

Espera, este no es el final de la historia. Si necesita buscar esclavos sin el conocimiento del maestro, entonces debe pensar en sus agregados y su modelo de objetos. Quizás necesite un segundo agregado donde el esclavo sea una raíz y luego debería tener un repositorio personalizado para ellos. El esclavo no es solo un hijo del maestro, sino una jerarquía separada que probablemente también tiene una referencia a un maestro. Es importante saber si un objeto esclavo puede existir sin un maestro en absoluto. Si puede, entonces un agregado separado es probablemente el camino a seguir.

Halcón
fuente
Muchas gracias por toda la información. Trataré de conseguir el libro de Eric para entender más.
JD01
mencionaste un segundo agregado, ¿es esto posible? ¿Estás diciendo que tenemos maestro como agregado raíz y también esclavo en el mismo modelo?
JD01
1
@ JD01: Absolutamente. Puede tener un agregado esclavo separado donde el esclavo es la raíz. Esto se ajusta a DDD siempre que tenga en cuenta que solo los objetos raíz están expuestos. Eso significa que no puede tener una tercera clase que no sea una raíz y sea parte de múltiples agregados. Pero puede tener un agregado esclavo al que también se hace referencia desde el agregado maestro como hijo. Sin embargo, esto es a menudo donde las cosas se complican (relaciones complejas, etc.). Intentamos simplificar eso aquí simplemente haciendo referencia a objetos DTO cuando alguna raíz necesita hacer referencia a otra raíz. Los DTO son de solo lectura y no se pueden cambiar.
Falcon
1
@ JD01: Por supuesto, esas referencias de DTO se pueden intercambiar, pero las DTO en sí mismas son inmutables. Entonces, si obtengo mi SlaveDto de un Maestro, no puedo cambiarlo. Cuando quiero cambiarlo, debo buscar su propio agregado y alterarlo allí. Esos DTO solo contienen datos planos, sin jerarquías y solo lo que es necesario.
Falcon
1
@ JD01: También debe preguntarse si un esclavo puede existir sin un maestro. Si no puede, entonces no es una raíz agregada. Mira mi pequeña actualización.
Falcon
1

En general, dentro del límite agregado debe haber solo un repositorio. Y, como dijo Falcon, podría terminar con dos agregados separados, maestro y esclavo.

Sin embargo, parece que el enfoque principal en su pregunta es la recuperación de datos, mientras que en DDD debería ser el comportamiento. Los límites agregados son una consecuencia de las restricciones impuestas por el comportamiento (cosas que cambian juntas e invariantes para que se apliquen), la estructura interna del agregado es una consecuencia de esa elección.

Por ejemplo, si agrupa las cosas correctamente de acuerdo con la necesidad de un cambio, no es necesario llamar a un Repositorio externo. La mayoría de los casos, los datos necesarios para una operación comercial en el Agregado ya deberían estar dentro de los límites agregados, la necesidad de acceder a diferentes agregados es probablemente un olor a límite inconsistente.

ZioBrando
fuente