Domain driven design en Bancolombia— De lo estratégico a lo táctico

Daniel Estiven Rico Posada
Bancolombia Tech
Published in
9 min readMar 24, 2020

La llegada de la nube hace que los negocios que usan tecnología para su funcionamiento tengan que transformarse. No solo presenta desafíos culturales, al ceder capacidades de infraestructura y de información a un tercero, sino que la nube replantea la forma en la que las aplicaciones deben construirse y nos llevan a pensarlas bajo el concepto de aplicaciones Cloud Native.

Cuando pensamos en aplicaciones cloud native es natural considerar una transición hacia sistemas distribuidos, promoviendo necesariamente una forma distinta de pensar acerca de cómo construir, desplegar, escalar y mantener software.

¿No sabes que son sistemas distribuidos? En este enlace te explican los principios básicos: https://dzone.com/articles/concepts-of-distributed-systems-part-1

El caso de las entidades Bancarias como el Grupo Bancolombia no es distinto. Desde hace algunos años nos planteamos el reto de repensar la nueva generación de aplicaciones del banco, promoviendo una serie de prácticas en pro de tener un adecuado aprovechamiento de las nuevas capacidades de infraestructura que nos ofrece la nube.

Estas prácticas tienen como foco potenciar el negocio desde la construcción de capacidades tecnológicas responsivas (con tiempos de respuesta consistentes), costo eficientes y confiables.

Diseño de software, ¿estructura o comportamiento? Los eventos son la clave…

“Object-Oriented Programming (OOP) taught us that we should begin our design sessions focusing on the things — the nouns — in the domain, as a way of finding the Domain Objects, and then work from there. It turns out that this approach has a major flaw: it forces us to focus on structure too early.”
(Bonér, J. (2017). Reactive Microsystems. O’Reilly Media, Inc.)

Photo by Alain Pham on Unsplash

Como lo plantea Jonas Bonér y como es promovido desde la academia y la industria es inadecuado que, en nuestros primeros esfuerzos de diseño de software pensemos en los objetos necesarios para modelar un problema del mundo real, principalmente cuando lo que estamos diseñando son sistemas distribuidos.

Con lo anterior estoy completamente de acuerdo. Autores como Russ Miles también han criticado este enfoque, apoyando la idea de que la esencia para entender un dominio está en el flujo de los datos (eventos) y en una exploración basada en una perspectiva de comunicación y no tanto en las decisiones estructurales previas a las que nos vemos forzados a tomar, cuando pensamos sólo en objetos y relaciones — al menos en una fase inicial — . (Bonér, J. (2017). Reactive Microsystems. O’Reilly Media, Inc.)

Por esta razón, en la industria surgieron principios de diseño que probaron ser muy útiles para construir sistemas distribuidos a escala. Estos principios son necesarios, porque al volcarnos al mundo de los sistemas distribuidos, nos podemos encontrar con prácticas abstractas y apasionantes, pero frustrantes en algunas ocasiones.

Lo abstracto se presenta en la detección de fallas, latencia, escalabilidad, ordenamiento de los datos, trazabilidad y consistencia eventual. Estas situaciones las debemos aprender a manejar para aprovechar los beneficios que nos dan los sistemas distribuidos en cuanto a la construcción de soluciones resilientes y elásticas, en donde tener una arquitectura sólida se hace estrictamente necesario.

Este entendimiento a nivel de sucesos (eventos) nos permite comprender cómo los cambios se propagan en el sistema, sus dependencias y los responsables de los datos. Esta información es muy relevante para consolidar una base de conocimiento sólida para un equipo sobre un dominio.

Estos principios de diseño no sólo son herramientas para pensar en sistemas distribuidos, sino que también permiten reducir los efectos secundarios del inadecuado entendimiento que se ha dado sobre las metodologías ágiles.

Diseño Efectivo y metodologías ágiles

Las primeras metodologías de desarrollo plantearon que la manera adecuada de construir software era hacer un diseño detallado de cada componente antes de iniciar la más mínima implementación. Con el tiempo, la experiencia mostró que era una estrategia inadecuada, porque los requerimientos y retos van evolucionando. Eventualmente, llegó entonces “la solución”: el agilismo.

La llegada del agilismo y quizás, su mala interpretación, generó un problema que considero que es igual de grave a un diseño excesivo: la falta o inexistencia del diseño de software.

Los equipos de desarrollo entraron en una dinámica de tomar tareas de un backlog que varía cada sprint e implementar el código que resuelve esa necesidad puntual, creando proyectos que dan una aparente sensación de velocidad hacia el negocio, pero que terminan siendo inmantenibles por no tener un norte claro a nivel de arquitectura.

DDD apoya el diseño efectivo de software evitando caer en procesos en cascada pero garantizando un norte claro a nivel de arquitectura, que sea coherente con procesos iterativos como los que plantean las metodologías ágiles.

Pero entonces, ¿qué es Domain driven design (DDD)?

DDD es un enfoque de desarrollo de software propuesto por Eric Evans en su libro: Domain-Driven Design — Tackling Complexity in the Heart of Software. Este enfoque busca una profunda conexión entre los conceptos y áreas del negocio y las arquitecturas aplicativas.

DDD tiene como objetivo facilitar el diseño e implementación de software que entregue alto valor a la organización, tanto desde un punto de vista estratégico como táctico, haciendo que los modelos de software reflejen las competencias core de la organización.

Una de las principales dificultades que es normal encontrarse en el proceso de entendimiento de DDD es: ¿cómo empezar a usarlo de manera práctica? debido a que inicialmente los conceptos suelen ser muy abstractos. Es importante saber qué DDD no es una tecnología ni tampoco una metodología.

La importancia de comprender que, DDD no es una metodología, es que, en sí mismo no ofrece una receta para un proceso de implementación paso a paso, sino más bien un marco de trabajo con diferentes herramientas utilizadas en diferentes fases del ciclo de desarrollo de software.

A continuación, presentaré las dos grandes fases que se plantean alrededor de Domain Driven Design y los beneficios específicos que hemos encontrado en cada una de ellas:

Modelado Estratégico

El modelado estratégico o DDD estratégico se enfoca en entender los diferentes contextos delimitados — y su lenguaje ubicuo* — los cuales tienen relación con el problema que se está modelando y busca agruparlos y clasificarlos en subdominios core*, de soporte* y genéricos*. Además, tiene como objetivo identificar los tipos de relaciones entre los contextos delimitados* para entender la dinámica del dominio.

*Lenguaje ubicuo: es una práctica que consiste en construir un lenguaje común y riguroso entre el equipo de tecnología y los usuarios (equipo funcional) con el objetivo de evitar la ambigüedad.

Contexto delimitado: son fronteras lógicas dentro de un modelo de dominio que cuentan con su propio lenguaje ubicuo.

Subdominios core: es la suma de los contextos delimitados más críticos del negocio, es el factor diferenciador, la razón de ser del modelado que se está realizando.

Subdominios de soporte: corresponde a los contextos delimitados que soportan funciones con relación directa al negocio pero a nivel de complemento.

Subdominios genéricos: son subdominios que responden a capacidades genéricas que pueden funcionar de la misma forma para cualquier organización sin ningún tipo de especialización o adaptación a nivel de negocio.

Un ejercicio de modelado estratégico debería permitirnos:

  • Crear un lenguaje ubicuo que pueda ser entendido tanto por el equipo de tecnología como por el equipo funcional, priorizando los conceptos propios del negocio.
  • Entender los subdominios impactados en una solución y la relevancia de cada uno de ellos desde un criterio de negocio.
  • Tomar decisiones alrededor de la tercerización: los subdominios core nunca deben ser tercerizados, los subdominios de soporte deberían evaluarse desarrollarlos in-house y los subdominios genéricos deberían poder tercerizarse sin mayor impacto.
  • Tomar decisiones relacionadas a las asignaciones de los equipos: los desarrolladores senior siempre deben trabajar en los dominios core. Los dominios adicionales pueden ser abordados por desarrolladores con menos experiencia.
  • Entender necesidades de negocio a alto nivel desde un modelado colaborativo, evitando los reprocesos que se generan al tener que contextualizar a varios equipos de la misma idea en espacios independientes.

¿Quién debería participar de las sesiones de modelado estratégico?

  • Arquitectos de Software
  • Expertos de dominio (negocio)
  • Líderes de tecnología involucrados

Y, ¿por dónde empiezo?

Estos conceptos son más fáciles de materializar si nos apoyamos de técnicas que nos faciliten el trabajo. En el caso del modelado estratégico es útil revisar Context Mapping. Hay que tener en cuenta que estas son las herramientas con las que hemos tenido experiencia y nos han sido de gran utilidad. Sin embargo, lo importante es lograr obtener el mapa de contextos, por tanto, si conoces herramientas adicionales, es válido utilizarlas mientras se llegue al mismo resultado — estas herramientas adicionales puedes compartirlas en los comentarios para que sean de utilidad para todos — .

El resultado debería verse de la siguiente forma:

(Brandolini, A. (2009). Strategic Domain Driven Design with Context Mapping . InfoQ)

Modelado Táctico

El modelado táctico es la siguiente fase del diseño orientado al dominio. Esta fase tiene como objetivo detallar las arquitecturas aplicativas y su materialización en código, siempre pensando en cuidar y aislar lo realmente relevante de una aplicación: el dominio.

A este nivel se busca un entendimiento detallado por parte del equipo de desarrollo de todos los flujos relevantes del negocio que serán materializados a través de la tecnología.

Las arquitecturas orientadas al dominio permiten materializar el modelo táctico en código, utilizando técnicas que aíslan y protegen al dominio de los detalles tecnológicos. Estos conceptos son tratados en detalle en este artículo:

¿Quién debería participar de las sesiones de modelado táctico?

  • Equipo implementador de la solución
  • Expertos de dominio (negocio)

Un ejercicio de modelado táctico debería permitirnos:

  • Entender y plasmar en un diagrama todos los flujos relevantes de negocio.
  • Tener un modelo de dominio claro y más refinado.
  • Tener una base clara sobre el tipo de arquitectura que utilizaremos.
  • Hacer una planeación inicial de la segregación a nivel de unidades desplegables del software a construir.
  • Estimar la infraestructura requerida.

Y, ¿por dónde empiezo?

Para lograr identificar los flujos de negocio y facilitar la generación de un modelo de dominio, es de gran utilidad hacer uso de una herramienta conocida como Event Storming.

Esta herramienta — creada por Alberto Brandolini en el marco de DDD — tiene como objetivo acelerar a través de un workshop el descubrimiento y entendimiento de dominios de negocio a través de los elementos definidos en la siguiente imagen:

(Brandolini, A. (2019). Introducing to Event Storming. LeanPub)

Cuando se tienen identificados los diferentes contextos delimitados que surgen del taller, pueden considerarse como el primer acercamiento a la cantidad de unidades desplegables óptimas para una solución, que será complementado con los requerimientos no funcionales y con los retos transaccionales que una solución pueda tener.

Después de tener identificados los dominios de negocio y en una fase más cercana a la implementación, puedes utilizar este plugin Open Source que hemos construido en Bancolombia para acelerar el proceso de desarrollo, y que está alineado a los planteamientos de arquitectura limpia de Robert C Martin:

En una etapa posterior, cuando ya tengas construidos algunos componentes y llegue la necesidad de planear la infraestructura requerida, es de gran utilidad hacer uso de esta herramienta para encontrar el momento de degradación de una aplicación, y que permite comprobar los principios planteados por la ley universal de la escalabilidad.

La idea es tener criterios para decidir las estrategias de escalamiento necesarias para soportar la transaccionalidad indicada en los requerimientos no funcionales del proyecto. La herramienta se enfoca en hacer pruebas de rendimiento desde nodos distribuidos:

Espero que el artículo sea descriptivo en cuanto los beneficios que ofrece un enfoque de desarrollo como DDD. Los invito a que el próximo proyecto que emprendan lo realicen con esta orientación y a que contribuyan a las diferentes iniciativas open source que desde Bancolombia estamos liderando.

Como desarrolladores está en nuestras manos apoyar el crecimiento de comunidades open source en Colombia y en general en Latinoamérica. Considero que podemos inclinar la balanza y aportar cada vez más a la construcción de tecnología y no sólo al uso.

Referencias Adicionales que me ayudaron en el proceso:

--

--