This post is also available in english.

Posts en esta serie:

En el post anterior de esta serie vimos cómo dividir un dominio complejo en subdominios menos complejos.

Cada subdominio va a tener su propio modelo, por ende vamos a tener muchos modelos conviviendo al mismo tiempo.

Si tuviésemos un único modelo, los conceptos de un área de negocio se podrían confundir con conceptos similares de otras áreas y esto generaría complejidad y acoplamiento. Domain-Driven Design nos propone separar un sistema grande en muchos modelos y proteger la integridad de cada uno para que sus conceptos se mantengan aislados, consistentes y protegidos. Esto se logra encapsulando cada modelo en un Bounded Context.

Idealmente vamos a contar con un Bounded Context por subdominio pero a veces no es el caso. A veces un subdominio puede contener varios Bounded Contexts o un Bounded Context abarcar más de un subdominio.

Espacio de la solución vs espacio del problema

Los subdominios están en el espacio del problema, del dominio. Surgen de analizar y descomponer el problema.

Por el otro lado los Bounded Contexts viven en el espacio de la solución, de las implementaciones en software.

Los Bounded Context son los subsistemas que implementamos (Por ejemplo un sistema de facturación, de inventario, etc.)

Estos subsistemas generalmente interactúan entre sí para poder brindar la funcionalidad general del sistema entero. Se suelen integrar mediante APIs u otros mecanismos que veremos más adelante.

Un Bounded Context puede estar compuestos por uno o más artefactos de software (aplicaciones, servicios, etc).

Un equipo por Bounded Context

Cada Bounded Context tiene un único equipo de desarrollo asociado.

Un equipo por Bounded Context

Sería complejo que varios equipos compartan un mismo modelo y repositorio de código. Deberían coordinar los cambios y las publicaciones a producción.

La colaboración y coordinación de múltiples equipos para poder implementar funcionalidades genera mucha ineficiencia innecesaria.

Con un equipo por modelo, cada uno itera su propio modelo, implementa funcionalidades y las publica en producción de forma independiente.

Eliminar la ambigüedad

Distintas áreas de la empresa suelen utilizar términos similares pero distintos, generando ambigüedad.

En una empresa de venta de tickets para recitales seguramente habrá áreas que se refieran a un ticket como una entrada aun evento, pero un área de soporte a clientes podría tener el concepto de ticket referido a un incidente o tema de soporte a atender. Ambos términos significan cosas distintas aunque llevan el mismo nombre.

Cada Bounded Context tiene su propio lenguaje ubicuo que elimina estas ambigüedades.

Un Bounded Context establece una frontera lingüística y contextual. En el Bounded Context de soporte un ticket significa un tema a resolver, en el de ventas significa un producto vendido.

Ambiguedad

Si por ejemplo nuestro dominio es el de una empresa editorial que se encarga de publicar libros, seguramente el concepto de libro esté presente en muchos subdominios pero no significa exactamente lo mismo.

Durante la etapa de redacción, el libro seguramente tenga borradores, un editor asignado y comentarios junto con un borrador final.

Los diseñadores gráficos crean el arte de tapa, los layouts e imágenes para la prensa.

Marketing no necesita todos los gráficos, solo el arte de tapa y descripciones de alto nivel.

Para el delivery seguramente se necesita saber la ubicación en el inventario, el stock disponible, las medidas y el peso.

Si tratásemos de modelar todas estas necesidades en un único objecto Libro, tendríamos un modelo muy complejo.

Una mejor alternativa es dividir en varios modelos (uno por cada subdominio atendiendo una problemática puntual) y que cada uno tenga su propio objeto Libro focalizado en atender las necesidades de cada contexto.

En el caso de un ecommerce nos sucedería algo similar con el concepto de Producto:

  • Para el catálogo un producto tiene imágenes, ficha técnica y descripción.
  • Para el inventario tiene stock.
  • Para marketing un producto tiene promociones y descuentos.

Modelar una única clase Producto para todos estos casos nos traería problemas y mucha complejidad.

Ambiguedad en Producto

Dividiendo la solución en varios Bounded Contexts tendríamos varios sistemas más chicos, cada uno con su clase Producto. La complejidad se reduciría y sería más fácil de manejar.

Producto en varios contextos

Implementación

Un Bounded Context es dueño de un slice vertical de funcionalidad desde la capa de presentación hasta la capa de almacenamiento de datos. Cada uno tiene autonomía para poder desarrollar y deployar sin afectar a los otros.

Slices verticales

A veces es común tener una misma interfaz de usuario compartida por varios contextos. En estos casos se suele utilizar una UI compuesta (como es el caso por ejemplo de Amazon).

UI compuesta

Próximo post

En el próximo post veremos como integrar varios Bounded Context para componer un sistema, tanto a nivel implementativo como a nivel político.