Blog Jose Cullar

//Scrum Master, Tech Lead & Full Stack Developer

Domain-Driven Design. Modules & Aggregates

por Jose el 31 octubre, 2016

Modules

Los módulos son contenedores de elementos que nos permiten la organización de nuestro dominio. Denominados técnicamente como packages o namespaces. El objetivo principal es desacoplar y organizar los elementos dependiendo del contexto al que pertenecen. Siguiendo en todo momento el lenguaje obicuo.

Module naming conventions for the model and submodules

Normalmente y si la compañía dispone de un nombre de dominio en internet, el módulo principal empezará con com. Seguido del nombre de la organización.

El siguiente segmento de nombre de módulo identifica el Bounded Context local donde se aloja el módulo o contenedor de elementos.

No se recomienda utilizar los nombres comerciales de los productos de la organización en los nombres de módulos o submódulos ya que éstos pueden cambiar a lo largo del tiempo y en ocasiones no guarda relación directa con la responsabilidad del Bounded Context al que pertenece. Es preferible identificar el nombre de cada Bounded Context según su responsabilidad a elección del equipo. El objetivo es reflejar el lenguaje obicuo de la organización.

Los siguientes segmentos deben identificar en qué parte del sistema se encuentra. En sistemas con arquitecturas por capas sería recomendable utilizar los nombres específicos según cada capa.

Aggregates

La clusterización o agrupación de entities y value objects forman un agregado. Encapsulando y alojando las relaciones que se establecen entre ellas actuando como un único conjunto.

Cada agregado dispone de una entidad raíz (aggregate root) de la que colgarán el resto de entities y value objects. Siempre que se desee modificar cualquier componente interno del agregado debe realizarse a partir de métodos accesibles en dicha entidad raíz manteniendo la integridad y estado del conjunto en memoria.




Fuente: Implementing Domain Driven Design.

En un enfoque Event-Driven dichos métodos accesibles serán los encargados de disparar los eventos facilitando la integración de agregados. Puedes echar un vistazo a Domain-Driven Design. Services & Domain Events.

Si las entities o value objects relacionados necesitan persistirse debe realizarse mediante la entidad raíz a través de servicios de aplicación y repositorios que orquestará las acciones de reconstrucción y persistencia del agregado según el caso de uso. Ya que se considera una mala práctica hacer uso de los repositorios desde métodos en el modelo de dominio.

Dada la regla de transacción por instancia de agregado y para satisfacer la concurrencia optimista y evitar el bloqueo de registros, existe la posibilidad de versionar las modificaciones de los agregados para evitar actualizar una versión anterior a la ya existente en base de datos.

Design Small Aggregates

No se recomienda diseñar grandes agregados. Dividiéndolos en la medida de lo posible en otros más pequeños. Permitiéndonos así ser más escalables trabajando con transacciones y lógicas más livianas y aisladas favoreciendo además la consistencia eventual mediante Domain Events en sistemas distribuidos.

Manteniendo pequeños agregados evitaremos reconstruir y persistir grandes cantidades de datos que puedan penalizar al rendimiento. Es aconsejable emplear técnicas como lazy loading que nos permitan cargas diferidas de sus dependencias.

No siempre es posible separar agregados, debido a posibles reglas de negocio que deban ser inmediatas y atómicas (en una misma transacción) mediante consistencia transaccional relacionadas a un único agregado (denominadas invariants). Deben discutirse con los expertos de dominio cada caso. Teniendo en cuenta siempre la regla de generar una única transacción por instancia de agregado.

Reference other Aggregates by Identity

Los agregados pueden relacionarse entre sí únicamente mediante los identificadores de su entidad raíz:




Fuente: Modeling Aggregates with DDD and Entity Framework.

Debemos evitar las propiedades asociativas conteniendo la instancia de la entidad root del otro agregado. Realizaremos dicha referencia mediante su identificador almacenado en un value object.

Model navigation

Manteniendo pequeños agregados y relacionándolos mediante identificadores nos ayuda a emplear Model navigation: técnica también conocida como modelo de dominio desconectado. Empleamos los repositorios o servicios de dominio para orquestar la carga de los objetos dependientes de los agregados a través de los servicios de aplicación gracias a los identificadores que lo componen.

Law of Demeter and tell, don´t ask

Ambas son principios de diseño que deben ser seguidos para diseñar los agregados. Los clientes que consumen el agregado no deben conocer los detalles de implementación, ni navegar entre referencias internas. Los atributos, propiedades, elementos y comportamientos internos del agregado no deben ser accesibles por el cliente.

La ley de Demeter no permite la navegación entre referencias internas de un agregado. Por otro lado Tell, don´t Ask permite la navegación a través del agregado, pero debemos encapsular/ocultar los detalles de implementación.

Puedes echar un vistazo a algunas leyes en el desarrollo de software y a los principios básicos en el desarrollo de software.

Example

Podemos resumir de forma muy gráfica uno de los ejemplos que explica Vaughn Vernon en Implementing Domain-Driven Design.

Dado el siguiente agregado, lo primero que debemos cuestionarnos es el tamaño y tipo de elementos con intención siempre de separarlo en varios, aplicando y desarrollándolo según recomendaciones:



Su representación en código:



A pesar que pueda ser atractivo crear grandes agregados, debemos dividirlo para obtener todos los beneficios que hemos comentado. Guardando la relación con sus identificadores, creando así nuevos agregados relacionados:



Tomando como ejemplo uno de los nuevos agregados creados y haciendo zoom, podemos ver sus elementos internos:



De igual modo, cualquiera de las relaciones de los nuevos agregados que creemos realizando la separación será mediante sus identificadores almacenados en value objects:



La complejidad en la implementación de agregados así como otros aspectos fundamentales como el rendimiento, consistencia e integración, dependerá en gran medida de como se diseñen/modelen.

Hasta aquí lo que creo más relevante en módulos y diseño de agregados.
Como siempre, te invito a que comentes cualquier tipo de aportación 🙂

Te dejo algunos enlaces interesantes para ampliar la información:

DDD Aggregate
Effective Aggregate Design
Implementing Domain-Driven Design: Aggregates
Domain-Driven Design: Aggregates Webcast at @AtrapaloEng (Spanish)

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *