Estoy aprendiendo DDD y, sin embargo, tengo más preguntas que respuestas.
Consideremos un modelo de un directorio que contiene una enorme cantidad de archivos.
Así es como lo veo:
El directorio es una raíz agregada.
Esta entidad debe tener la lógica de validación de verificar la unicidad del nombre del archivo cuando se agrega o se renombra. Y la entidad File contiene la lógica 'SetName', que notifica al Directorio a través del Evento de Dominio sobre los cambios de nombre.
Pero, ¿cómo debería funcionar el directorio?
No siempre es posible cargar todos los archivos en la memoria. ¿Debería en este caso el repositorio de archivos tener lógica adhoc para verificar la unicidad del nombre? Supongo que es una decisión viable.
Sin embargo, ¿qué sucede si algunos archivos ya se han agregado o renombrado dentro de una transacción actual aún no confirmada? (nada lo prohíbe. Los límites de las transacciones se establecen externamente en relación con la lógica empresarial). Probablemente el repositorio debe tener en cuenta tanto los estados en memoria como los persistentes (fusionar estos estados puede ser una tarea no trivial).
Entonces, cuando la raíz agregada con todos sus elementos secundarios cabe en la memoria, todo está bien. Y tan pronto como no puedas materializar todas las entidades, hay problemas.
Me gustaría saber cuáles son los enfoques para tales situaciones. Puede que no haya ningún problema en absoluto y es solo debido a mi malentendido sobre el tema.
fuente
Respuestas:
Mi respuesta está sesgada con el gran libro de Vaughn Vernon Implementing Domain Driven Design (una lectura obligada)
1. Favorecer los agregados pequeños.
Si voy a modelar su dominio, modelaría un
Directory
como agregado yFile
como otro agregado.2. Agregados de referencia por id.
Por
Directory
lo tanto tendrá una colección deFileId
objetos de valor.3. Use fábricas para crear agregados.
Para un caso simple, un método de fábrica puede ser suficiente
Directory.addFile(FileName fileName)
. Sin embargo, para casos más complejos, usaría una fábrica de dominios.La fábrica de dominios podría validar que
fileName
es única utilizando ayFileRepository
unUniquefileNameValidator
servicio de infraestructura.¿Por qué modelar
File
como un agregado separado?Porque
Directories
no están hechos deFiles
. aFile
está asociado con un ciertoDirectory
. Además, piense en un directorio que tenga miles de archivos. Cargar todos estos objetos en la memoria cada vez que se recupera un directorio es un factor decisivo para el rendimiento.Modele sus agregados de acuerdo con sus casos de uso. Si sabe que nunca habrá más de 2-3 archivos en un directorio, puede modelarlos como un agregado único, pero en mi experiencia las reglas de negocio cambian todo el tiempo y paga si su modelo era lo suficientemente flexible como para acomodar cambios
Obligatorio leer Diseño Agregado Efectivo por Vaughn Vernon
fuente
inode
sistemas Unix.File
puede existir uno con Nombre dadoDirectory
, es decir,Directory
tiene la invariante: Unicidad de nombre. Al menos es importante para elDirectory
, pero no para elFile
. En realidad, @AlexanderLanger tiene razón: muchas carpetas pueden hacer referencia a 'Archivo'. Y el Nombre es probablemente la propiedad de esta referencia en lugar de laFile
propia. Okay. Entonces, la funcionalidad de cambio de nombre pertenece alDirectory
, pero de nuevo, no es una buena idea almacenar miles de identidades referenciadas.bool ContainsFileOfName(int folderId, string fileName)
. Después de eso, la firma del método 'Renombrar' puede ser la siguiente:void Rename(int fileId, string newName)
donde dentro de algunosIFolderService
(que envuelve el repositorio) se resuelve y se le pregunta si existe ese nombre.Esta no es una pregunta DDD per se. La pregunta principal aquí es sobre el contexto de sincronización (que aquí es una raíz agregada).
Volviendo al tema: el directorio bloqueará en algún objeto de sincronización de nombres de archivos y realizará una verificación si el nombre de archivo dado está permitido, que es O (n) en el peor de los casos.
fuente
Aunque algunos pueden decir que intente cambiar su diseño, siempre es necesario que un AR tenga una gran lista de objetos simples. Y almacenarlos en la memoria no es lo mejor desde una perspectiva de rendimiento, sin embargo, todo lo que necesita hacer en tales casos es preservar los límites de la transacción. Una solución simple es la siguiente:
Algunas restricciones:
fuente