DDD: ¿el repositorio de una raíz agregada maneja los agregados de ahorro?

27

Estoy usando un enfoque similar a DDD para un módulo greenfield de una aplicación existente; no es 100% DDD debido a la arquitectura, pero estoy tratando de usar algunos conceptos DDD. Tengo un contexto acotado (creo que ese es el término apropiado, todavía estoy aprendiendo sobre DDD) que consta de dos Entidades: Conversationy Message. La conversación es la raíz, ya que un mensaje no existe sin la conversación, y todos los mensajes en el sistema son parte de una conversación.

Tengo una ConversationRepositoryclase (aunque en realidad es más como una puerta de enlace, uso el término "repositorio") que encuentra conversaciones en la base de datos; cuando encuentra una conversación, también crea (a través de Fábricas) una lista de mensajes para esa conversación (expuesta como una propiedad). Esta parece ser la forma correcta de manejar las cosas, ya que no parece ser necesaria una MessageRepositoryclase completa, ya que solo existe cuando se recupera una conversación.

Sin embargo, cuando se trata de guardar un mensaje, ¿es responsabilidad del ConversationRepository, ya que es la raíz agregada del mensaje? Lo que quiero decir es, ¿debería tener un método en ConversationRepository llamado, digamos, AddMessageque toma un mensaje como parámetro y lo guarda en la base de datos? ¿O debería tener un repositorio separado para buscar / guardar mensajes? Lo lógico parece ser un repositorio por Entidad, pero también he escuchado "Un repositorio por Contexto".

Wayne Molina
fuente

Respuestas:

25

El libro azul es definitivamente vale la pena leer si quieres sacar el máximo partido del enfoque DDD. Los patrones DDD no son triviales y aprender la esencia de cada uno de ellos lo ayudará a reflexionar sobre cuándo usar qué patrón, cómo dividir su aplicación en capas, cómo definir sus agregados, etc.

El grupo de 2 entidades que está mencionando no es un Contexto limitado, es probable que sea un Agregado. Cada agregado tiene una raíz agregada, una entidad que sirve como un único punto de entrada al agregado para todos los demás objetos. Por lo tanto, no existe una relación directa entre una Entidad y otra Entidad en otro Agregado que no sea la Raíz Agregada.

Los repositorios son necesarios para apoderarse de entidades que no se obtienen fácilmente al atravesar otros objetos. Los repositorios generalmente contienen Raíces Agregadas, pero también puede haber Repositorios de Entidades regulares.

En su ejemplo, la conversación parece ser la raíz agregada. Tal vez las conversaciones son el punto de partida de su aplicación, o tal vez desee consultarlas con criterios detallados para que no sean accesibles de manera satisfactoria a través del simple recorrido de otros objetos. En tal caso, puede crear un Repositorio para ellos que le dará al código del cliente la ilusión de un conjunto de Conversaciones en memoria para consultar, agregar o eliminar directamente. Los mensajes, por otro lado, se obtienen fácilmente al atravesar una conversación, y es posible que no desee recibirlos de acuerdo con criterios detallados, solo todos los mensajes de una conversación a la vez, por lo que es posible que no necesiten un repositorio.

ConversationRepository desempeñará un papel en los mensajes persistentes, pero no un papel tan directo como usted menciona. Por lo tanto, no AddMessage () en ConversationRepository (ese método pertenece más bien a la conversación en sí), sino que cada vez que el repositorio persista una conversación, es una buena idea persistir sus mensajes al mismo tiempo, ya sea de forma transparente si usa un marco ORM como (N) Hibernate, usando SQL ad hoc si así lo elige, etc.

guillaume31
fuente
1
Si una raíz agregada, como Conversation, tiene muchos tipos de entidades diferentes, como Message, Thingies y Wingies, cuando guarde una conversación, por ejemplo ConversationRepo.save (conversación), ¿cómo sabe qué entidades necesita? ¿Ser salvado? En el ejemplo de carteles anterior, solo se deben guardar las entidades de mensaje. ¿Atraviesa todas las colecciones posibles dentro de la raíz agregada para encontrar entidades sin identificadores?
chris-richards
3

Puede crear ConversationService e inyectar IConversationRepository e IMessageRepository en su constructor. Utilice repositorios para operaciones CRUD simples y servicios para todo lo demás (almacenamiento en caché, lógica de guardado, etc.)

šljaker
fuente
1
¿no está salvando la lógica CRUD?
Timothy Groote