Frecuentemente, en DDD, un pobre diseño del modelo tiende a centrarse en las entidades y los objetos valor sin prestar atención a las relaciones entre dichos objetos del dominio. Por defecto, se crean las asociaciones que reflejan la vida real o, peor aún, el modelo de datos subyacente.
Es importante recordar que el modelo de dominio no es lo mismo que el modelo de datos y su objetivo es apoyar las invariantes (reglas que hacen cumplir la consistencia en el modelo de dominio) y los casos de uso en lugar de las interfaces de usuario. Siempre debemos modelar las asociaciones de los objetos del dominio basándonos en los requerimientos de los casos de uso.
A continuación os muestro los tres errores frecuentes que a mi parecer se producen en el tratamiento incorrecto en las relaciones entre los objetos del dominio.
Primer error: relaciones bidireccionales innecesarias
El primer error en el tratamiento de las relaciones entre los objetos del dominio es crearlas innecesariamente de tipo bidireccional, es decir, dos objetos en los que cada uno de ellos contiene una relación el uno al otro. Los ORM han puesto fácil la tarea de crear este tipo de relaciones bidireccionales en código y esto puede dar lugar a la carga de grafos de objetos profundos desencadenando un rendimiento de ejecución degradado.
Consideremos el ejemplo de un sistema de compras donde un cliente tiene facturas y, a su vez, dichas facturas tienen sus respectivas líneas donde se indican los productos comprados.
Supongamos que solamente queremos modificar el NIF del cliente, ¿es necesario cargar todas sus facturas de compra con sus respectivos productos?. Como podemos observar una relación bidireccional añade complejidad técnica y oscurece el concepto del dominio.
Para simplificar esto debemos limitar las relaciones en una única dirección y para ello nos debemos preguntar lo siguiente:
- ¿Cuál es el comportamiento que debe cumplir la asociación?
- ¿Quién necesita que la relación esté funcionando?
Segundo error: referencias a objetos versus identificadores
El segundo error en el tratamiento de las relaciones entre los objetos del dominio es utilizar referencias a objetos innecesarias en vez de usar sus identificadores. El modelado de relaciones con referencias a objetos incrementa la complejidad.
Considerando el ejemplo anterior de un sistema de compra, un cliente en la vida real tiene muchas facturas pero a nivel de aplicación puede no haber invariantes que requieran que un objeto cliente disponga de la colección con todas sus facturas.
El siguiente fragmento de código puede ser lento debido a que el objeto cliente debe ser cargado para el caso de uso de crear una factura.
El método alternativo para implementar las asociaciones es almacenar el identificador del objeto y usar un repositorio dentro de un servicio de aplicación para buscar los objetos del dominio que se requieran para un caso de uso en concreto. Al utilizar el repositorio se reduce la complejidad y las referencias a objetos en el modelo.
Para determinar si es necesaria una referencia a objeto nos tenemos que hacer la siguiente pregunta:
- ¿Está apoyando la asociación a una invariante de dominio para un caso de uso específico?
En el ejemplo anterior un cliente tiene facturas pero una factura solamente necesita el identificador de un cliente para satisfacer las invariantes.
Tercer error: no limitar las asociaciones implementadas como referencias a objetos
El tercer error en el tratamiento de las relaciones entre los objetos del dominio es el no limitar el número de objetos que se necesita recuperar (hidratar) en las asociaciones implementadas como referencias a objetos que son necesarias para apoyar invariantes del dominio.
Partiendo del ejemplo anterior del sistema de compra, supongamos que por requerimientos del dominio, la entidad cliente tiene una asociación establecida con la entidad factura (una relación de uno a muchos implementada como referencia a objeto). Un cliente tiene muchas facturas pero para conocer la cantidad de facturas pendientes de cobro en el periodo actual el sistema solamente necesita conocer las facturas vigentes en el mes en curso. Cargando todas las facturas del cliente reduce el rendimiento del sistema y esto es totalmente innecesario.
Para optimizar el rendimiento tenemos que aplicar una limitación a nivel de acceso a datos usando, por ejemplo, el siguiente fragmento de código donde se recupera el grafo de objetos cliente y sus facturas correspondientes para el periodo especificado.
Conclusiones finales
Reducir y limitar las relaciones entre los objetos del dominio simplifica la complejidad y refleja una visión más profunda del dominio. Pero aún nos queda aplicar el patrón Agregado (http://bit.ly/1T0aJYW) que nos ayude a reducir aún más la complejidad, estableciendo un poco de orden en este conjunto de relaciones que puede llegar a ser complicado de manejar.
Si quieres saber más sobre cómo SOGETI puede ayudarte, visita nuestra web.
Óscar Fernández González es un desarrollador de software para la plataforma .NET de Microsoft prácticamente desde sus orígenes con la versión 1.0 lanzada en Enero de 2002. Se incorporó a Sogeti en Octubre de 2007, donde ha desarrollado aplicaciones para clientes de diversos sectores como sector bancario, seguros y publicidad.
0 comments on “Tratamiento incorrecto en las relaciones entre los objetos del dominio”