20. Agregados: límites de consistencia y protección de reglas internas

20.1 Introducción

Un agregado es un grupo de objetos del dominio que se tratan como una unidad para proteger reglas de consistencia. Puede contener una entidad principal, otras entidades internas y objetos de valor. Su objetivo es definir un límite claro: qué cosas deben mantenerse coherentes juntas y quién controla los cambios.

Los agregados son especialmente útiles cuando el modelo empieza a tener varias entidades relacionadas y reglas internas. Sin límites claros, cualquier parte del sistema podría modificar objetos relacionados de forma desordenada y romper invariantes del dominio.

20.2 Imagen conceptual de agregado

Agregado de dominio con raíz de agregado, entidades internas, objetos de valor y límite de consistencia protegiendo reglas internas

20.3 Qué es un agregado

Un agregado es un conjunto de objetos del dominio que se modifican y validan como una unidad. Dentro de ese conjunto hay una entidad principal llamada raíz de agregado, que controla el acceso y protege las reglas internas.

Un agregado define un límite de consistencia: dentro de ese límite, las reglas importantes deben mantenerse válidas.

Por ejemplo, Pedido puede ser raíz de un agregado que contiene Ítems de pedido. El pedido controla que exista al menos un ítem antes de confirmarse y que el total sea coherente con sus ítems.

20.4 Límite de consistencia

El límite de consistencia indica qué objetos deben mantenerse válidos juntos después de una operación. Si una regla exige que varios objetos cambien de forma coordinada, puede ser una señal de que pertenecen al mismo agregado.

Por ejemplo, si al agregar un ítem a un pedido debe recalcularse el total y verificarse una cantidad máxima, esas reglas pertenecen al límite del agregado Pedido. No conviene que un objeto externo modifique ítems directamente sin pasar por el pedido.

20.5 Raíz de agregado

La raíz de agregado es la entidad principal que representa al agregado desde afuera. Las operaciones externas deberían acceder al agregado a través de esa raíz. Las entidades internas no deberían modificarse libremente desde cualquier lugar.

Si Pedido es raíz, el sistema no debería agregar un Ítem de pedido directamente sin que Pedido aplique sus reglas. Si Agenda es raíz, la incorporación de Franjas horarias debería pasar por Agenda para evitar superposiciones o inconsistencias.

20.6 Invariantes internos

Los agregados protegen invariantes internos. Algunos ejemplos:

  • Un Pedido confirmado debe tener al menos un Ítem.
  • El total de un Pedido debe ser coherente con sus Ítems.
  • Una Agenda no debe tener Franjas horarias superpuestas.
  • Un Turno reservado debe tener Paciente y Franja horaria.

Si una regla debe cumplirse siempre dentro de un conjunto de objetos, conviene analizar si esos objetos forman un agregado.

20.7 Ejemplo: agregado Pedido

En un sistema de ventas, Pedido puede ser un agregado. Tiene identidad, estado, reglas de confirmación y una colección de Ítems de pedido. Los ítems forman parte del pedido y normalmente no tienen sentido fuera de él.

El agregado Pedido puede proteger reglas como: no confirmar un pedido vacío, no permitir cantidades negativas, recalcular total, impedir cambios si ya fue enviado o registrar eventos cuando se confirma.

20.8 Ejemplo: agregado Agenda

En un sistema de turnos, Agenda puede ser un agregado si controla sus Franjas horarias y reglas de disponibilidad. Una regla interna podría indicar que dos franjas no pueden superponerse. Otra puede indicar que una agenda publicada debe tener franjas válidas.

Si las franjas se modifican sin pasar por Agenda, se podría romper la consistencia. Por eso, Agenda puede ser la raíz que controla altas, bajas, bloqueos y publicación.

20.9 Agregado no es tabla ni módulo

Un agregado no es una tabla de base de datos ni necesariamente un módulo técnico. Es un límite conceptual de consistencia. Puede terminar almacenado en una o varias tablas, documentos o estructuras, pero esa decisión pertenece al diseño técnico.

Confundir agregado con tabla lleva a modelos incorrectos. La pregunta central no es cómo se guarda, sino qué reglas deben mantenerse coherentes juntas.

20.10 Agregado no es toda relación de composición

Que exista una relación todo-parte no significa automáticamente que haya un agregado. La composición conceptual ayuda a identificar pertenencia, pero el agregado se define por reglas de consistencia y control de cambios.

Puede haber partes que pertenezcan a un todo, pero que no necesiten un límite de consistencia complejo. También puede haber reglas entre objetos relacionados que exijan tratarlos como unidad aunque la relación no parezca una composición tradicional.

20.11 Tamaño del agregado

Un agregado debe ser lo suficientemente grande para proteger sus reglas internas, pero no más grande de lo necesario. Agregados demasiado grandes se vuelven difíciles de entender, modificar y mantener. Agregados demasiado pequeños pueden no proteger invariantes importantes.

El tamaño se decide analizando reglas de consistencia. Si dos objetos no necesitan cambiar juntos para mantener invariantes, quizá no deberían estar dentro del mismo agregado.

20.12 Referencias entre agregados

Los agregados pueden relacionarse entre sí, pero conviene evitar que uno modifique directamente el interior de otro. Desde el punto de vista conceptual, un agregado debería respetar los límites de otro y comunicarse a través de su raíz o mediante eventos.

Por ejemplo, un Turno puede referenciar un Paciente, pero eso no significa que el agregado Turno pueda modificar libremente el historial interno del Paciente. Cada agregado protege sus propias reglas.

20.13 Consistencia inmediata y eventual

Dentro de un agregado, las reglas importantes suelen requerir consistencia inmediata: al terminar una operación, el agregado debe quedar válido. Entre agregados distintos, algunas consecuencias pueden resolverse después mediante eventos o procesos separados.

Por ejemplo, al cancelar un turno, el agregado Turno debe quedar en un estado válido. Notificar al paciente o actualizar estadísticas puede ocurrir como consecuencia posterior. Esta separación ayuda a mantener límites más claros.

20.14 Tabla de ejemplos

La siguiente tabla muestra posibles agregados:

Agregado Raíz Reglas protegidas
Pedido con ítems Pedido No confirmar pedido vacío; total coherente con ítems.
Agenda con franjas Agenda Franjas sin superposición; publicación válida.
Turno Turno Estado válido; paciente requerido si está reservado.
Factura con detalles Factura Detalles válidos; total e impuestos coherentes.
Cuenta con movimientos Cuenta Saldo coherente; movimientos válidos según política.

20.15 Preguntas para descubrir agregados

Estas preguntas ayudan a identificar límites de agregado:

  • ¿Qué reglas deben cumplirse siempre juntas?
  • ¿Qué objeto debería controlar los cambios internos?
  • ¿Qué invariantes se romperían si se modifican partes por separado?
  • ¿Qué entidad representa al conjunto desde afuera?
  • ¿Qué objetos internos no deberían modificarse directamente?
  • ¿El conjunto es más grande de lo necesario?
  • ¿Las consecuencias externas pueden resolverse mediante eventos?

20.16 Errores frecuentes

Al modelar agregados, suelen aparecer estos errores:

  • Crear agregados enormes que incluyen demasiados conceptos.
  • Crear agregados demasiado pequeños que no protegen invariantes.
  • Confundir agregado con tabla, módulo o pantalla.
  • Permitir modificar entidades internas sin pasar por la raíz.
  • Incluir objetos solo porque están relacionados, sin una regla de consistencia.
  • No definir qué invariantes protege cada agregado.
  • Ignorar consecuencias entre agregados y mezclarlas dentro del mismo límite.

20.17 Qué debes recordar de este tema

  • Un agregado agrupa objetos que deben mantenerse consistentes juntos.
  • La raíz de agregado controla el acceso y protege reglas internas.
  • El límite del agregado se define por invariantes y consistencia, no por tablas.
  • Las entidades internas no deberían modificarse libremente desde afuera.
  • Un agregado debe ser tan pequeño como sea posible y tan grande como sea necesario.
  • Entre agregados pueden existir relaciones, pero cada uno protege sus propias reglas.
  • Los eventos ayudan a coordinar consecuencias fuera del límite del agregado.

20.18 Conclusión

Los agregados ayudan a controlar la complejidad del modelo de dominio. Definen límites de consistencia, protegen invariantes y evitan que cualquier parte del sistema modifique objetos internos sin reglas claras. Un buen agregado no se define por estructura técnica, sino por las reglas del negocio que necesita preservar.

En el próximo tema estudiaremos con más detalle las raíces de agregado, su responsabilidad principal y el acceso controlado al interior del agregado.