Capítulo 1. Lo que aprendí de DDD. Conceptos básicos
DDD, Arquiectura Hexagonal, Event Sourcing, Lenguaje ubicuo…
Uno de los propósitos del año 2020 fue profundizar en el enfoque DDD y arquitectura hexagonal empleando mi framework favorito (Symfony) como punto de partida. Algunas de las ideas que extraje ya las he mencionado en el curso de Symfony que tenéis disponible en mi canal de Youtube.
Hoy comienzo una serie de artículos en los que daré forma a todas las notas que tomé durante el año pasado con el objetivo de acercaros un poco más las ideas fundamentales en las que se basa DDD.
¿Me acompañas?
¿Qué es DDD?
La idea del enfoque DDD (siglas de Domain — Driven — Design) es muy sencilla: alinear a todos los equipos involucrados en el desarrollo de un producto:
Lograr una comunicación fluida y bidireccional entre el equipo de negocio y el de desarrollo.
Asegurar que el producto desarrollado responde a las expectativas de negocio.
Facilitar la iterabilidad y mantenibilidad del producto.
Esta es la razón de que en DDD el “lenguaje ubicuo” tenga tanta importancia. Definirlo al comienzo del desarrollo de un producto de largo alcance es el que nos permitirá que software y negocio trabajen bajo el mismo dominio de ideas.
Un ejemplo “tontorrón” en el desarrollo de un blog: el lenguaje ubicuo nos servirá para evitar que la parte de negocio hable de “artículos” mientras que el software tenga entidades llamadas “posts”.
¿Es DDD “el bálsamo de fierabrás”?
No, DDD no siempre es la solución óptima: este enfoque implica mucho más tiempo y una mayor implicación de todo el equipo que un desarrollo normal. Además, trasladar el dominio de negocio al software obliga a seguir determinados estándares que permitan portar esas ideas a las entidades y servicios de la aplicación. Quédate con esta idea:
DDD nos anima a acercar lo máximo posible la lógica de negocio a nuestras entidades de dominio.
Por tanto, antes de lanzarte a implementar un proyecto con una aproximación basada en dominio asegúrate de que dispondrás del tiempo y la involucración adecuadas.
Arquitecturas recomendadas
A continuación os dejo 4 arquitecturas que os permitirán en mayor o menor medida darle un enfoque DDD a vuestros proyectos.
La idea subyacente cuando implementamos DDD es conseguir separar lo máximo posible el dominio de nuestro aplicación de la infraestructura que empleamos para implementar el proyecto (“separation of concerns”). Es decir, si estamos empleando Symfony para desarrollar el proyecto, lo deseable será que nuestras entidades de dominio desconozcan por completo la existencia del ORM Doctrine o de cualquiera de los componentes que nos ofrece Symfony para implementar funcionalidad.
Patrón MVC
El archiconocido patrón modelo-vista-controlador permite separar en 3 capas un proyecto:
El modelo, que es dónde reside la lógica de nuestra aplicación.
La vista, es decir, la representación de dicho modelo.
El controlador, encargado de recibir la petición y trasladarla al modelo para generar la vista.
Este patrón es el que yo estoy siguiendo (de momento) en el curso de Symfony que os enlacé al principio. Es cierto que su adopción obliga al modelo a conocer detalles de la infraestructura (por ejemplo, los repositorios). Sin embargo, si lo organizamos adecuadamente y nos esforzamos en abstraer lo máximo posible el uso del framework, creo que podemos lograr un buena aproximación sin recurrir a la dosis extra de tiempo que requieren el resto de arquitecturas propuestas.
Arquitectura hexagonal
La idea de la arquitectura hexagonal es separar por completo la infraestructura del dominio.
En este caso, cada círculo sólo puede ver aquello que queda dentro de él:
La capa de dominio es dónde se encuentra la lógica de negocio.
La capa de aplicación se encarga de orquestar el dominio, decidiendo las llamadas que es necesario hacer a cada entidad de negocio.
La capa es la que provee de la “chicha”: ORM, controladores… Es decir, la implementación de las operaciones y acciones que hemos definido en nuestro dominio.
Además, en arquitectura hexagonal cobran especial importancia los eventos de dominio, que representan acciones que han ocurrido dentro de nuestro sistema.
CQRS
CQRS (Command-Query-Reponsability-Segregation) da una vuelta más a la arquitectura anterior: no sólo se separan las capas de nuestro proyecto sino que divide en dos las operaciones que nuestro sistema puede procesar:
Una petición (devuelve un resultado).
Un comando (produce una mutación, es decir, un cambio en el sistema).
Por tanto, CQRS promueve la idea de tener dos bases de batos distintas:
la de escritura, que actúa como fuente de verdad de nuestro sistema.
la de lectura, que modelará las diferentes vistas de nuestra aplicación.
El proceso por el cual la “base de datos” de escritura se comunica con la de lectura se conoce como proyección.
Event Sourcing
La última vuelta de tuerca a las arquitecturas que promueven una mejor implementación del enfoque DDD es la conocida como event sourcing.
Aquí, los “eventos de dominio” cobran vital importancia, pues son los que van a guardarse en base de datos para reconstruir el estado de una entidad.
Dicho de otro modo, si estamos creando un blog bajo el enfoque “event sourcing”, no dispondremos de una tabla “article”, sino que tendremos una tabla dónde aparezcan todos los eventos que se han producido en torno a los artículos de nuestro sistema:
ArticleCreated
ArticleTitleEdited
ArticleImageEdited
ArticleMovedToDraft
Como supondréis, este enfoque es bastante complicado de implementar, pero a cambio obtendremos el registro de todo lo ocurrido en nuestro sistema, facilitando su depuración y mantenibilidad.
🙏🏻 Gracias a Garaje de Ideas
Los amigos de Garaje de ideas patrocinan Latte and Code y buscan talento: http://bit.ly/garaje-tech-talento
Conclusiones
Y hasta aquí el artículo de hoy. Sé que me he dejado en el tintero ideas como los “bounded contexts” y que el resumen de las distintas arquitecturas es eso, un resumen.
En posteriores capítulos seguiré profundizando en estos y nuevos conceptos. ¡Tengo material para aburrir!