2008-08-24 10 views
15

DDD establece que solo debe acceder a las entidades a través de su raíz agregada. Por ejemplo, supongamos que tiene una raíz agregada X que potencialmente tiene un lote de entidades Y de niños. Ahora, para algunas situaciones, solo te importa un subconjunto de estas entidades Y a la vez (quizás las muestres en una lista paginada o lo que sea).¿Se me permite tener agregados "incompletos" en DDD?

¿Está bien implementar un repositorio entonces, para que en tales escenarios devuelva agregado incompleto agregado? Es decir. un objeto X cuya colección Ys solo contiene las instancias Y que nos interesan y no todas de ellas? Esto podría causar, por ejemplo, métodos en X que realicen algunos cálculos que impliquen el Ys para no comportarse como se espera.

¿Es esto quizás una indicación de que la entidad Y en cuestión debe considerarse promovida a una raíz agregada?

Mi idea actual (en C#) es aprovechar la ejecución retrasada de LINQ, de modo que mi objeto X tenga un IQueryable para representar su relación con Y. De esta manera, puedo tener una carga diferida transparente con filtrado ... Pero hacer que esto funcione con un ORM (de Linq a Sql en mi caso) podría ser un poco complicado.

¿Alguna otra idea inteligente?

Respuesta

1

Realmente está haciendo dos preguntas superpuestas.

  1. El título y la primera mitad de su pregunta son filosóficos/teóricos. Creo que la razón para acceder a entidades solo a través de su "raíz agregada" es abstraer los tipos de detalles de implementación que está describiendo. El acceso a través de la raíz agregada es una forma de reducir la complejidad al tener un punto de acceso confiable. Está eliminando la fricción/ambigüedad/incertidumbre al adherirse a una convención. No importa cómo se implemente en la raíz, simplemente sabes que cuando solicites una entidad estará allí. No creo que esta perspectiva excluya un "repositorio filtrado" como describes. Pero para proporcionar un pit of success para que los desarrolladores caigan, debería ser imposible crear una instancia del repositorio sin ser explícito sobre su "filtrado"; Del mismo modo, si es posible el acceso compartido a una instancia de repositorio, la "filtración" debe ser explícita cuando se codifica en la persona que llama.

  2. La segunda mitad de su pregunta es acerca de la implementación en una plataforma específica. No estoy seguro de por qué menciona la ejecución retrasada, creo que es realmente ortogonal a la pregunta de filtrado. El filtrado en sí podría ser un poco complicado de implementar con LINQ. Tal vez, en lugar de indicar el lugar donde lambdas, configura una colección de ellos y selecciona uno según el filtro que necesites.

6

considero una raíz agregado con un montón de entidades secundarias que ser un olor código o un olor DDD si se quiere. :-) Generalmente veo dos opciones.

  1. Divida su agregado en muchos agregados más pequeños. Esto significa que mi diseño original no era óptimo y necesito identificar algunas entidades nuevas.
  2. Divida su dominio en múltiples contextos delimitados. Esto significa que hay conjuntos específicos de escenarios que usan un subconjunto común de las entidades en el agregado, mientras que hay otros conjuntos de escenarios que usan un subconjunto diferente.
+1

Podría ser un olor a código, pero también podría ser no. He tenido el mismo problema. Tengo una clase Trace que posee puntos de referencia geográficos. Ahora esta traza puede ser arbitrariamente larga y, aunque la Traza misma es una entidad, los puntos de referencia no lo son. Ellos son objetos de valor. Entonces, si quiero actualizar el Trace en el sentido puro de DDD, tendría que cargar el Trace de raíz agregado completo con todos sus puntos de referencia, agregar algunos waypoints y almacenar el Trace completo nuevamente. Esto, obviamente, no escala para trazas grandes. Por lo tanto, debido a problemas de rendimiento, me veo en la posibilidad de permitir raíces agregadas parcialmente cargadas ... –

2

Jimmy Nilsson insinúa en su libro que, en lugar de leer un agregado completo, puede leer una instantánea de partes de él. Pero se supone que no puede guardar los cambios en las clases de instantáneas en la base de datos.

Jimmy Nilsson's book Capítulo 6: Preparación de la infraestructura: consulta. Página 226.

Snapshot pattern

0

se le permite ya que el código se compilará todos modos, pero si usted va para un diseño puro DDD no debe tener instancias incompletas de objetos.

Debe tener en cuenta LazyLoading si tiene miedo de cargar un objeto enorme del cual solo usará una pequeña porción de sus entidades secundarias.

LazyLoading demora la carga de lo que usted decida cargar de forma diferida hasta el momento en que se acceda a ellos. Hacen uso de devoluciones de llamada para llamar al método de carga una vez que el código los llama.

Cuestiones relacionadas