Introducción a Domain Drive Design – DDD
En esta nueva entrada vamos a ver una introducción a Domain Drive Design, en el qué veremos qué es y por qué deberíamos usarlo. De todos modos, este modelo o diseño tiene mucho que profundizar por lo que un libro que recomiendo leer o al menos echar un ojo es Tackling Complexity in the Heart of Software de Eric Evans.
El diseño orientado o basado en dominios tiene como objetivo principal que el software que estamos desarrollando o implementado refleje el sistema del mundo real que estamos intentando desarrollar.
Dentro del DDD podríamos definir un dominio como aquella unidad de conocimiento en torno a la cual se centra o gira la lógica del negocio o lógica empresarial que se quiere implementar.
Podríamos decir que el Dominio, es la unidad básica en torno a la cual va a girar todos nuestro desarrollo, va a ser el corazón de nuestra aplicación.
Este artículo se ha realizado teniendo en cuenta por un lado el libro de Eric Evans y por otro lado en la experiencia personal al aplicar este modelo.
Objetivo de aplicar DDD y qué es
Podríamos decir, aunque resulte muy obvio, que el objetivo principal de aplicar DDD o Domain Driven Design en inglés, es poder aislar el código que pertenece al dominio de los detalles técnicos de impletación. De esta manera lo podemos tratar de manera independiente y así centrarnos en la complejidad de cada uno.
Si nos orientamos a un desarrollo orientado al dominio hay que tener en cuenta que hará falta un equipo concienciado y preparado para este tipo de desarrollo. Por un lado necesitaremos a los expertos del dominio y por otro lado a los desarrolladores que formarán parte del lado técnico.
En un sistema tradicional tendríamos a un analista que sería el que hablaría con el equipo de negocio y las necesidades serían trasladadas al equipo de desarrollo, dedicándose estos últimos únicamente a la parte de programación. Este enfoque tradicional, solía acarrear algún que otro problema, como omisión de alguna información, falta de entendimiento o tener que decidir los desarrolladores alguna implementación por falta de conocimiento del negocio.
Es por el motivo anterior, que este sistema busca una mayor interacción entre los programadores y el equipo de negocio. De esta manera se logrará un mayor entendimiento y ambos podrán estar involucrados de una manera mucho más activa. Por ejemplo Eric Evans, en su libro sobre DDD, define Ubiquitous Language para crear una manera de comunicación estándar entre el equipo de desarrollo y de negocio, de manera que la información fluya con facilidad.
Todo lo anterior acarrea una curva de aprendizaje y un mayor incremento en los costes del proyecto al menos al principio. Pero a la larga repercutirá en una disminución de los costes y en un software mucho más fiable y con una mayor capacidad para poder realizar test sobre los dominios que se van creando.
Hay que tener en cuenta que este tipo de orientación, suele ser aplicada a desarrollos algo complejos y grandes en donde nuevas funcionalidades pueden ir apareciendo, o para sistemas legacy para poder ir migrandolos a otras tecnologías. Por lo que se facilita la creación de nuevas piezas que podrán interactuar entre si en una constante evolución.
Principios centrales del DDD
Podríamos decir que la orientación al dominio se centra en tres pilares básicos:
- Centrarse en el dominio central y la lógica de negocio.
- Convertir diseños complejos en modelos de dominio.
- Constante interacción y colaboración con los expertos de dominio, lo que ayudará a solventar dudas e interactuar más con el equipo de desarrollo.
Términos comunes en DDD
En DDD hay una serie de términos comunes que defino a continuación:
- Context: Es el escanario en el que aparece una palabra, y este escencario define su significado. Esta sentencias o palabras solo son entendibles en su contexto.The setting in which a word or statement appears that determines its meaning. Statements about a model can only be understood in a context.
- Model: Un modelo es una abstración de un sistema que describe aspectos de un dominio.
- Ubiquitous Language: Es un lenguaje estructurado y definido para un modelo de dominio y usado y entendido por todos los miembros.
- Bounded Context: Un Bounded Context define la descripción de un límite dentro del cual se define y aplica un modelo concreto. Por lo general, suele ser un equipo específico o un subsistema.
Estructura de Domain Drive Design
Cuando trabajamos con DDD hay tres partes que debemos tener en cuenta:
- Separación de responsabilidades en capas, aislar el dominio
- Modelar y definir el modelo.
- Gestionar el ciclo de vida de los objetos de Dominio.
Separación de responsabilidades en capas: Aislar el dominio
Como hemos comentado anteriormente, DDD se centra en separar el modelo del desarrollo. Para ello hay que aislar el dominio y separar en capas que sean legibles y entendibles.
Podríamos hacer esta división siguiendo la siguiente estructura en capas:
- Presentación.
- Aplicación.
- Dominio.
- Infraestructura.
Una arquitectura que podría perfectamente encajar con esa solución y se acopla muy bien al DDD, es la arquitectura hexagonal o de puertos y adaptadores.
Capa de presentación
Muestra la información al usuario.
Aplicación
Esta capa define los casos de uso que son trasladados al software. Se intentará mantener tan simple como sea posible y se encargará de delegar las tareas de los objetos de dominio a la siguiente capa.
Dominio
La capa de dominio será la responsable de representar los conceptos del negocio, así como reglas y situaciones particulares.
Hay que tener en cuenta que esta capa es la principal del negocio.
Infraestructura
Esta capa permite la interacción entres las 4 capas a través de algún framework. Es en donde reside la parte técnica de la aplicación.
Modelar y definir el modelo
La definición del modelo consistirá en ser capaces de describir todo el conocimiento del dominio con estructuras y conceptos que ayudarán a implementarlo a entender mejor el dominio y debatir.
Lo hay que tener claro es que el dominio ayuda a la definición de funciones y a realizar una representación del conocimiento de la vida real.
Una de las técnicas, que suele ayudar a la representación del modelo es el uso de Ubiquitous Language. De este modo, tanto desarrolladores como gente de negocio son capaces de entenderlo.
En este punto la interacción con los expertos del dominio es muy importante, tanto ellos como el equipo de desarrollo tienen que estar muy involucrados. Cualquier cambio en el modelo afectará al desarrollo, por lo que el uso de diagramas y un lenguaje común será clave para el éxito del proyecto.
Para definir un modelo vamos a usar tres herramientas diferentes:
- Value Objects
- Entities
- Services
Value objects
Estos objetos definen funcionalidades y tienen significado. Estos objetos suelen ser pasado como parámetros en mensajes entre los objetos, por lo general se crean temeporalmente para alguna operación y luego son descartados.
Entities
Una entidad es un objeto definido principalmente por su identidad en lugar de por atributos específicos. Por lo general una entidad tendrá un identificador único que lo hará diferente a un value object.
Services
Para aquellos casos en los que se tenga que realizar alguna operación que no pertenece a algún objeto, podemos crear algún servicio en el modelo.
Gestionar el ciclo de vida de los objetos de Dominio
En un desarrollo orientado al dominio, uno de los objetivos es evitar que el modelo que hemos creado se vea afectado por el ciclo de vida de la propia apliación. Es por este motivo que separamos la lógica del negocio con el ciclo de vida.
Cuando separamos la lógica de negocio con el ciclo de vida, aparecen dos nuevos conceptos, agregados y repositorios
Agregados: Los agregados son un conjunto de entities y value objects que tienen sentido a nivel de dominio y se crean y persisten juntos. Agregan estructuras al modelo.
Repositorios: ofrece una interfaz para agregar y persitir agregados. El repositorio se comunica y conecta a la base de datos de manera que ocultan los detalles del domino con la base de datos. En la capa de dominio se crearán las interfaces pero será en la capa de infraestructura donde reside la lógica de comunicación con Base de Datos. Con esta aproximación y haciendo uso de interfaces, podemos realizar cambios en la capa de persitencia sin afectar al modelo ni lógica de negocio.
Conclusión
Como hemos visto en esta introducción a Domain Drive Design – DDD, este modelo nos ayudará en la construcción de nuestras arquitecturas de software, aunque con una curva de aprendizaje que en ocasiones se puede hacer dura, la recompensa merece la pena.
Domain Drive Design daría para muchos más artículos y se podría profundizar mucho más, por eso recomiendo el libro de Eric Evans Implementing Domain-Driven Design o Tackling Complexity in the Heart of Software.