This post is also available in english.

Posts en esta serie:

Domain Driven Design (diseño dirigido por el dominio) o DDD es una filosofía de desarrollo de software creada por Eric Evans en su libro Domain-Driven Design: Tackling complexity in the heart of software (también conocido como el “blue book”).

Permite a los equipos manejar de forma efectiva la construcción y mantenimiento de software para dominios de problema complejos.

La forma de arquitectura más común por lejos en aplicaciones de negocio es la Big Ball of Mud (BBoM) o Gran bola de lodo. Este tipo de arquitectura se define como una jungla de código spaghetti, estructurada al azar, descuidada, unida con cinta adhesiva y alambre.

tangledCrédito: Imagen de GarryKillian en Freepik

Una de las principales razones que llevan a caer en este tipo de arquitectura es que se mezclan las complejidades propias del dominio (la complejidad esencial) con las complejidades técnicas (la complejidad accidental).

Los proyectos de software suelen fallar cuando no se entiende suficientemente bien el dominio de negocio en el cual se está trabajando.

Sacando los requerimientos no-funcionales (performance, seguridad, etc) la parte difícil es el modelado de un dominio que pueda cumplir con los casos de uso del negocio.

Domain Driven Design hace que los programadores y los expertos de negocio trabajen en conjunto para construir el software.

Además, DDD le permite al negocio aprender más sobre si mismo. Ningún experto de negocio suele conocer todo acerca del mismo. Con DDD todos aprenden porque genera un proceso continuo de descubrimiento.

El conocimiento se centraliza y todos tienen acceso al mismo, no hay conocimiento parcial que solo tengan los programadores o que esté aislado en cada departamento o grupos de la empresa.

No existen traducciones de términos entre los expertos de negocio, los programadores y el software. Se construye un lenguaje compartido que todos hablan.

DDD nos provee patrones para entender correctamente el dominio y poder construir una solución de software que es útil para resolver problemas dentro del mismo.

Los patrones de DDD se clasifican principalmente en dos grupos:

Destilar el dominio del problema

El dominio es lo que hace una organización y el mundo en el cual lo hace.

Cada organización tiene su propio know-how y su forma de hacer las cosas. Ese conocimiento y sus métodos particulares para llevar a cabo sus operaciones es lo que conocemos como el dominio del problema.

Es importante destilar este dominio para poder determinar que es importante y que no. Cuando tenemos un software grande no todo tiene que estar diseñado de forma perfecta, es una perdida de tiempo y de costos.

Los equipos de desarrollo y los expertos de negocio destilan en conjunto dominios grandes y complejos y los descomponen en subdominios más pequeños y manejables.

Por ejemplo, una empresa que vende productos online podría identificar los siguientes subdominios:

  • Catálogo de productos
  • Ordenes de compra
  • Facturación
  • Cobranza
  • Delivery de los productos
  • Inventario y gestión de stock
  • Soporte

Subdominios E-Commerce

Para poder descubrir y entender el dominio entero se suelen organizar workshops y utilizar prácticas como ser:

Un negocio contiene una gran cantidad de información, no toda sirve para resolver los problemas que se quieren resolver. Se necesita destilar esta información para poder construir un modelo que sea efectivo para resolver los casos de uso del negocio. A esta actividad se la conoce como Knowledge Crunching.

Ejemplo de event stormingCrédito:  Robert Laszczak

Descomponer el dominio de problema

Como dijimos, la destilación nos revela que el dominio esta compuesto por distintos subdominios. No todos son igualmente importantes para el negocio. Todos son esenciales para que el sistema entero funcione pero algunos son mas valiosos que otros.

No se debe poner el mismo esfuerzo y calidad en todo el sistema. Esto nos va a llevar a perder el foco de aquellas áreas donde es esencial que un negocio se focalice.

Podemos identificar tres tipos de subdominios.

Subdominios core

Estos subdominios son los más importantes. Son la razón por la cual estamos construyendo un software en vez de comprarlo.

Los subdominios core le dan al negocio la principal ventaja competitiva. Es donde el negocio debe sobresalir.

Que hace a nuestro sistema de e-commerce distinto de la competencia? Quizás tenemos un sistema de delivery muy eficiente que entrega los productos en el día o quizás los reviews de usuarios de los productos.

En este tipo de subdominios debemos poner el mayor esfuerzo y los mejores programadores.

Subdominios genéricos

Son subdominios que suelen estar presentes en varios negocios y sistemas. Por ejemplo un servicio de envío de emails, de reportes, de facturación, etc.

Estos subdominios no tienen ninguna especialización sino que son problemas comunes de varias empresas.

Si bien no son centrales (no son core), son necesarios para el funcionamiento de la empresa.

No tiene mucho sentido invertir mucho esfuerzo en estos subdominios porque no nos van a dar una ventaja competitiva. Podemos buscar comprar software o desarrollar soluciones con menos foco y con programadores juniors.

Subdominios de soporte (Supporting)

Estos subdominios no son core pero tampoco son soluciones genéricas. Son problemas donde la empresa tiene alguna especialización que la distingue de otras empresas.

Por ejemplo puede ser que el control de inventario no sea algo central pero sin embargo tiene muchas particularidades respecto a como lo hacen otras empresa.

En este caso de subdominios tampoco conviene invertir mucho esfuerzo. Conviene buscar soluciones que se puedan customizar.

A veces se pueden resolver sin necesidad de hacer un desarrollo de software sino con procesos manuales (liberando a los programadores para trabajar en los subdominios core.)

Tipos de subdominios

Crear modelos efectivos

Para acercarnos a resolver los problemas con software vamos a enfocarnos primero en los modelos que debemos crear. Modelos que representaremos luego en software.

En vez de hacer un gran modelo de nuestro dominio de problema (lo cual nos llevaría a tener un modelo muy complejo), hacemos un modelo por cada subdominio.

Un modelo es una abstracción que creamos con el fin de poder satisfacer los requerimientos del negocio.

Para evitar la complejidad accidental (la complejidad técnica) aislamos los modelos de los aspectos técnicos y de infraestructura.

No todos los modelos se crean igual. Se eligen los patrones de diseño más apropiados de acuerdo a la complejidad y las necesidades de cada subdominio. Los modelos genéricos o de soporte pueden no necesitar un diseño rico orientado a objetos y pueden tener arquitecturas más procedurales u orientadas a datos.

Un error común es buscar que los modelos se correspondan con la realidad. Un modelo es una abstracción útil diseñada para nuestro contexto particular. Un mapa geográfico o político son dos modelos con fines totalmente distintos. Y son abstracciones, no son la realidad del terreno.

Un modelo debe incluir aspectos que ayuden a resolver problemas de negocio y deben evitar detalles irrelevantes.

Mapa de subte de Londres

Si vemos el mapa de subtes de Londres este modelo esta diseñado para mostrar las estaciones y las combinaciones. Pero este modelo no incluye las distancias reales. Su utilidad es para que podamos saber que subte tomamos y poder llegar a destino, no para entender a nivel geográfico la exactitud de cuán lejos está una estación de otra.

Resumiendo entonces:

  • Los negocios suelen ser grandes y complejos, no hay que intentar modelar todo.
  • Los modelos deben ser abstracciones útiles y deben ser refinados constantemente.
  • No hay que modelar todas las relaciones que existen entre los conceptos de la vida real.

Otra cuestión que debemos tener cuidado es respecto al uso de las abstracciones. Cuando modelamos los conceptos en objetos seguramente vamos a diseñar objetos mas concretos y objetos más abstractos.

Hay que tener cuidado con el uso de las abstracciones, siempre tienen un precio y por ende deben limitarse.

Es mejor ser explícito y repetirse que intentar juntar conceptos levemente relacionados u ocultar un concepto de negocio importantes bajo capas de abstracciones.

Modelo del subdominio de catálogo de productos

Lenguaje ubícuo

El verdadero valor de DDD está en la colaboración entre los desarrolladores y los expertos de negocio para producir un mejor entendimiento del negocio.

Para llegar a un buen entendimiento se deben poder comunicar de forma efectiva. Esto se logra creando un lenguaje compartido donde todos hablan utilizando los mismos términos sin necesidad de traducciones. Este lenguaje se denomina lenguaje ubícuo.

La creación de un lenguaje ubícuo permite a los equipos organizar el modelo mental y el modelo del código fácilmente. Da claridad y consistencia.

Este lenguaje debe utilizar los conceptos de negocio y se expresa en todos lados: conversaciones, diagramas, documentación y en el código fuente.

Por la rigurosidad que se requiere al momento de programar muchas veces se descubren nuevos conceptos que deben incorporarse al lenguaje ubícuo. Estos conceptos se discuten en conjunto con la gente de negocio y se acuerdan nuevas definiciones para desambiguar. Un lenguaje ubícuo está en constante evolución, se van refinando términos e incorporando nuevos.

Este aspecto de DDD es clave para que los desarrolladores y los expertos de negocio puedan crear y evolucionar el modelo en colaboración.

El código expresando el modelo en este lenguaje le permite a cualquier persona poder entender con claridad los procesos de negocio, los conceptos y como se relacionan entre sí. Si por ejemplo estamos haciendo un software de contabilidad, cualquier persona que lea el código fuente aprendería de contabilidad.

Próximo post

Hablamos en este post sobre la importancia de poder entender el dominio de problema y descomponerlo en subdominios menos complejos. Hablamos sobre como categorizar estos subdominios para poder entender donde conviene poner el foco, vimos que por cada uno vamos a construir un modelo (que luego representaremos en software) y la importancia de que este modelo este expresado en un lenguaje ubícuo que desarrolladores y expertos de negocio puedan evolucionar en conjunto.

En el próximo post de esta serie vamos a hablar sobre como proteger la integridad de estos modelos para que no se contaminen entre sí (algo que inevitablemente llevaría a incrementar la complejidad nuevamente). Vamos a introducir el concepto de Bounded Contexts.