El diseño estratégico es la parte de DDD que decide cómo dividir un dominio grande en piezas manejables y coherentes. En la lección anterior aprendimos a clasificar subdominios; ahora vamos a trazar los límites concretos del modelo dentro del software mediante el concepto más importante de todo DDD: el Bounded Context (contexto delimitado). Junto a él estudiaremos el Lenguaje Ubicuo, el vocabulario compartido que mantiene alineados a negocio y desarrollo. Esta lección importa porque es donde DDD conecta directamente con la arquitectura: los límites que tracemos aquí determinarán, por ejemplo, las fronteras de nuestros microservicios. Equivocarse en estos límites es una de las causas más caras de fracaso en sistemas distribuidos.

Contenido

  1. El problema: un mismo término, significados distintos
  2. Lenguaje Ubicuo
  3. Bounded Context (contexto delimitado)
  4. Relación entre Bounded Contexts y microservicios
  5. Ejemplo integrado en una aseguradora

  1. El problema: un mismo término, significados distintos

En cualquier organización mediana, las mismas palabras significan cosas diferentes según el departamento. Pensemos en la palabra "Cliente" en una aseguradora:

  • Para el área Comercial, un Cliente es un lead con datos de contacto y un historial de interacciones de venta.
  • Para el área de Suscripción, un Cliente es un perfil de riesgo con edad, profesión y siniestralidad previa.
  • Para el área de Facturación, un Cliente es una cuenta con domiciliación bancaria, recibos y deudas.

Si intentamos crear una única clase Cliente gigante que sirva a todos, obtenemos un objeto enorme, lleno de campos que solo algunos usan, con reglas contradictorias y que nadie puede modificar sin miedo a romper otra área. Este es el clásico "modelo único para toda la empresa", y siempre fracasa en dominios complejos.

DDD propone lo contrario: aceptar que el significado depende del contexto y trazar límites explícitos.

  1. Lenguaje Ubicuo

El Lenguaje Ubicuo (Ubiquitous Language) es un vocabulario común, riguroso y compartido entre desarrolladores y expertos del dominio, que se usa en todas partes: en las conversaciones, en la documentación y —crucialmente— en el código.

Principios:

  • Cada término tiene un significado único y preciso dentro de su contexto.
  • Si el negocio dice "suscribir una póliza", el código tiene un método suscribir(), no create() ni save().
  • El lenguaje evoluciona: cuando se descubre un matiz, se actualizan a la vez el lenguaje hablado y el código.

Veamos la diferencia que produce en el código:

// SIN Lenguaje Ubicuo: nombres técnicos genéricos
public class PolicyManager {
    public void process(PolicyData data) { /* ... */ }
    public void update(Long id, int status) { /* ... */ }
}

Problemas del fragmento anterior:

  • PolicyManager, process y update no dicen nada del negocio. ¿Qué procesa? ¿Qué actualiza?
  • El estado se representa con un int: nadie sabe qué significa status = 2.
  • Un experto del dominio no podría leer este código ni validar que hace lo correcto.
// CON Lenguaje Ubicuo: el código habla el idioma del negocio
public class Poliza {
    public void suscribir(Suscriptor suscriptor) { /* ... */ }
    public void rechazarPorRiesgoExcesivo(MotivoRechazo motivo) { /* ... */ }
    public void renovar() { /* ... */ }
}

Aquí:

  • Los nombres suscribir, rechazarPorRiesgoExcesivo y renovar son exactamente los verbos que usa el negocio.
  • Los tipos Suscriptor y MotivoRechazo son conceptos del dominio, no datos primitivos sueltos.
  • Un experto del dominio puede leer y entender lo que hace la clase, lo que permite detectar errores de modelado en conversación, sin ejecutar nada.

El Lenguaje Ubicuo es el puente que elimina la traducción constante entre "lo que dice el negocio" y "lo que escribe el programador".

  1. Bounded Context (contexto delimitado)

Un Bounded Context es una frontera explícita dentro de la cual un modelo de dominio y su Lenguaje Ubicuo tienen un significado único y consistente. Fuera de esa frontera, los mismos términos pueden significar algo distinto, y eso está bien.

Cada Bounded Context tiene:

  • Su propio modelo de dominio.
  • Su propio Lenguaje Ubicuo (la palabra "Cliente" puede modelarse de forma diferente en cada uno).
  • Sus propias reglas de negocio y, normalmente, su propia base de datos.

Volviendo al ejemplo del "Cliente":

Bounded Context Cómo modela al "Cliente" Atributos relevantes
Ventas Lead / Prospecto Datos de contacto, fase del embudo, comercial asignado
Suscripción Asegurado / Perfil de Riesgo Edad, profesión, historial de siniestralidad
Facturación CuentaDeCliente Forma de pago, recibos, saldo pendiente

La idea radical es: no existe un único "Cliente". Existen tres modelos distintos, cada uno óptimo para su contexto, que comparten una identidad referenciada (un identificador común) pero no la misma estructura. Cómo se comunican esos contextos lo veremos en la lección 06-04 (Context Mapping).

graph LR
    subgraph BC_Ventas[Bounded Context: Ventas]
        L[Lead]
    end
    subgraph BC_Suscripcion[Bounded Context: Suscripcion]
        A[Asegurado]
    end
    subgraph BC_Facturacion[Bounded Context: Facturacion]
        C[CuentaDeCliente]
    end
    L -. mismo cliente real .-> A
    A -. mismo cliente real .-> C

Sobre este diagrama Mermaid (graph LR, de izquierda a derecha):

  • Cada subgraph representa un Bounded Context con su frontera explícita.
  • Dentro de cada contexto vive un modelo distinto del "cliente": Lead, Asegurado, CuentaDeCliente.
  • Las flechas punteadas (-.->) indican que se refieren a la misma persona real, pero no comparten el mismo modelo de código: están conectadas por identidad, no por estructura.

  1. Relación entre Bounded Contexts y microservicios

Existe una correspondencia natural —pero no obligatoria— entre los Bounded Contexts y los microservicios:

Concepto Bounded Context (DDD) Microservicio (arquitectura)
Naturaleza Frontera lógica de un modelo Unidad física de despliegue
Define Significado consistente de los términos Proceso independiente, API, BD propia
Relación Es un buen candidato a microservicio Idealmente, alinea su frontera con un BC

La buena práctica es: un microservicio debería contener uno o varios Bounded Contexts completos, nunca partir un Bounded Context entre varios microservicios. Si partes un contexto, repartes su modelo y sus reglas entre servicios distintos, lo que genera un acoplamiento fortísimo y comunicación constante.

Los Bounded Contexts ofrecen el criterio de descomposición que los equipos de microservicios suelen echar en falta. Sin DDD, muchos parten los servicios por entidades técnicas ("servicio de usuarios", "servicio de pedidos") y acaban con un monolito distribuido.

Ejemplo de cómo un Bounded Context se traduce en la configuración de un microservicio independiente:

# despliegue del microservicio que implementa el Bounded Context de Suscripcion
apiVersion: apps/v1
kind: Deployment
metadata:
  name: suscripcion-service        # un BC = un servicio desplegable
spec:
  replicas: 2
  template:
    spec:
      containers:
        - name: suscripcion
          image: registry.fiatc/suscripcion:1.4.0
          env:
            - name: DB_URL
              value: jdbc:postgresql://db-suscripcion:5432/suscripcion  # BD propia

Comentarios sobre este YAML de Kubernetes:

  • name: suscripcion-service deja claro que el servicio corresponde a un único Bounded Context (Suscripción).
  • image referencia la imagen de contenedor de ese contexto, versionada de forma independiente.
  • La variable DB_URL apunta a db-suscripcion: una base de datos propia y exclusiva del contexto. Otros contextos no acceden a ella directamente; eso preserva la frontera.

  1. Ejemplo integrado en una aseguradora

Pongamos todo junto. Una aseguradora podría organizar su sistema en estos Bounded Contexts:

graph TD
    V[Ventas] --> S[Suscripcion]
    S --> P[Gestion de Polizas]
    P --> SI[Gestion de Siniestros]
    P --> F[Facturacion]
    SI --> F

Lectura del diagrama:

  • Ventas capta interesados; cuando uno acepta, pasa a Suscripción.
  • Suscripción evalúa el riesgo y, si lo aprueba, Gestión de Pólizas crea la póliza.
  • Gestión de Siniestros y Facturación dependen de la póliza vigente.

Cada uno de estos contextos tiene su propio Lenguaje Ubicuo: en Ventas se habla de "Lead" y "oportunidad"; en Siniestros, de "parte", "perito" e "indemnización". Forzar un vocabulario único entre todos ellos sería un error.

Errores Comunes y Consejos

  • El modelo único corporativo. Intentar que una sola clase Cliente o Producto sirva a toda la empresa. Resultado: un objeto inmanejable. Acepta la multiplicidad de modelos.
  • Bounded Contexts demasiado pequeños. Si cada entidad es su propio contexto, tendrás cientos de servicios diminutos hablando entre sí sin parar. El contexto debe ser cohesionado, no atómico.
  • Confundir frontera lógica con frontera física. Un Bounded Context es un concepto lógico de DDD; un microservicio es una decisión de despliegue. Puedes empezar con varios contextos dentro de un mismo monolito (un monolito modular) y separarlos en servicios solo cuando haga falta.
  • No mantener vivo el Lenguaje Ubicuo. Si el negocio cambia un término y el código no, el puente se rompe. Refactoriza los nombres cuando cambie el lenguaje.
  • Consejo: organiza tus paquetes Java por Bounded Context (com.fiatc.suscripcion, com.fiatc.siniestros), no por capa técnica (controllers, services). El paquete debe gritar el dominio.

Ejercicios

Ejercicio 1. Elige el término "Producto" en una tienda online y describe cómo lo modelarías de forma distinta en al menos dos Bounded Contexts (por ejemplo, Catálogo e Inventario).

Ejercicio 2. Reescribe la siguiente firma de método aplicando Lenguaje Ubicuo del dominio de siniestros: void update(Long id, int type, String text).

Ejercicio 3. Un equipo ha dividido su sistema en "servicio-base-de-datos", "servicio-lógica" y "servicio-frontend". Explica por qué esta división no se corresponde con Bounded Contexts y propón una alternativa.

Soluciones

Solución 1. En el contexto de Catálogo, un Producto es contenido de marketing: nombre, descripción, fotos, precio de venta, categorías. En el contexto de Inventario, el mismo producto es una ReferenciaDeStock: SKU, unidades disponibles, ubicación en almacén, punto de reposición. Comparten el identificador del producto, pero sus atributos y reglas son distintos.

Solución 2. Una posible reescritura: void registrarParteDeSiniestro(IdSiniestro id, TipoSiniestro tipo, DescripcionDanos descripcion). Los nombres reflejan los conceptos del negocio y los tipos sustituyen a los primitivos genéricos.

Solución 3. Esa división es técnica por capas, no por dominio: cada "servicio" necesita a los otros para hacer cualquier cosa, lo que produce un acoplamiento total y comunicación constante (un monolito distribuido). Una alternativa basada en Bounded Contexts sería dividir por capacidades de negocio —por ejemplo, "Suscripción", "Pólizas", "Siniestros"— donde cada servicio contiene su propia lógica, datos e interfaz de su parte del dominio.

Conclusión

Hemos visto que el diseño estratégico trata de trazar fronteras: el Lenguaje Ubicuo garantiza que negocio y código hablen el mismo idioma, y el Bounded Context delimita el alcance dentro del cual ese idioma y su modelo son consistentes. Hemos comprobado que un mismo concepto del mundo real ("Cliente", "Producto") se modela de forma distinta en cada contexto, y que estos contextos son los mejores candidatos para definir las fronteras de los microservicios, evitando el temido monolito distribuido.

En la siguiente lección, "Diseño Táctico: Entidades, Agregados y Repositorios", bajaremos del mapa estratégico al detalle de implementación: veremos con código Java cómo construir el modelo rico dentro de un Bounded Context usando los patrones tácticos de DDD.

Curso de Arquitectura de Aplicaciones

Módulo 1: Fundamentos de la Arquitectura de Aplicaciones

Módulo 2: Principios y Tácticas de Diseño

Módulo 3: Estilos y Patrones Arquitectónicos

Módulo 4: Arquitecturas Distribuidas y Microservicios

Módulo 5: Arquitecturas Dirigidas por Eventos y Mensajería

Módulo 6: Diseño Dirigido por el Dominio (DDD)

Módulo 7: Datos y Persistencia

Módulo 8: Arquitectura en la Nube y Despliegue

Módulo 9: Calidad, Seguridad y Observabilidad

Módulo 10: Evolución, Gobernanza y Casos Prácticos

© Copyright 2026. Todos los derechos reservados