Domain-Driven Design (DDD) Básico
Nivel intermedio-avanzado — Lenguaje Ubicuo y Bounded Contexts para estructurar sistemas complejos alineados con el negocio.
El problema
El negocio dice "cliente" y piensa en la persona que compra. El desarrollador escucha "cliente" y piensa en la tabla de la base de datos. Cuando construyen un sistema con "Cliente" como entidad central, descubren que "Cliente" significa algo diferente en ventas, soporte, facturación y marketing.
Situación típica: el sistema tiene una tabla Cliente con 47 columnas. Algunas solo aplican a prospectos, otras solo a clientes activos, otras solo para el área contable. Nadie sabe qué campos usar para qué. Cada cambio a Cliente rompe algo en otro módulo. // un modelo que intenta ser todo termina sin servir bien a nadie
Herramienta 1: Lenguaje Ubicuo
Vocabulario compartido entre desarrolladores y expertos del dominio. Cada término tiene una definición precisa que ambos grupos entienden igual — sin sinónimos, y específico de cada bounded context.
Cómo construirlo: escucha al experto ("¿qué significa exactamente 'procesar el pedido'?"), cuestiona los términos genéricos ("Cliente", "Producto" casi siempre esconden complejidad), documenta en glosario con definición + ejemplos + contra-ejemplos, y úsalo literalmente en el código: si el experto dice "Pedido", la clase se llama Pedido, no Order ni PedidoDTO.
Herramienta 2: Bounded Contexts
Un límite explícito dentro del cual un modelo de dominio particular es válido. Dentro del contexto, los términos tienen significado preciso; fuera, pueden significar algo distinto.
| Término | Contexto Ventas | Contexto Soporte | Contexto Facturación |
|---|---|---|---|
| Cliente | Prospecto o comprador potencial | Usuario con ticket abierto | Entidad con cuenta por pagar |
| Producto | Oferta con precio y features | Item con documentación y FAQs | Línea en factura |
| Pedido | Oportunidad de venta | Referencia para consulta | Origen de factura |
En lugar de un modelo "Cliente" que intenta ser todo, DDD propone modelos distintos por contexto. Cómo identificarlos: por organización (equipos distintos suelen indicar contextos distintos), por ciclo de vida (el concepto cambia de significado con el tiempo), por reglas de negocio (validaciones distintas según el área), o por Event Storming (los "pivotal events" marcan fronteras).
Herramienta 3: Context Mapping
Una vez identificados los bounded contexts, hay que definir cómo se relacionan:
| Patrón | Descripción | Cuándo usarlo |
|---|---|---|
| Shared Kernel | Comparten parte del modelo | Equipos muy alineados |
| Customer-Supplier | Upstream define, downstream consume | Relación de dependencia clara |
| Conformist | Downstream se adapta totalmente | No hay poder de negociación |
| Anti-Corruption Layer | Downstream traduce modelo externo | Integración con legacy |
| Open Host Service | Upstream publica API abierta | Múltiples consumidores |
| Separate Ways | No hay integración | Sistemas independientes |
Cuándo aplicarlo
| DDD completo si... | Solo glosario si... |
|---|---|
| Dominio complejo, muchas reglas de negocio | CRUD simple con poca lógica |
| Múltiples equipos en el mismo sistema | Un solo equipo pequeño |
| Sistema de larga vida (>3 años) | MVP o proyecto temporal |
Es tentador asumir que cada bounded context se convierte automáticamente en un microservicio. No es así: un bounded context es un límite de modelo, no de despliegue. Puedes tener varios bounded contexts dentro de un mismo monolito bien modularizado — la decisión de separarlos en servicios independientes es arquitectónica y depende de los trade-offs que ya viste en la Lección 1.3, no de DDD por sí solo.
Practica: sistema de e-commerce
Sistema que incluye: catálogo de productos, carrito de compras, procesamiento de pedidos, gestión de inventario, y atención al cliente.
Construye un glosario de Lenguaje Ubicuo (mínimo 5 términos), identifica los bounded contexts, y crea un Context Map indicando qué patrón de relación aplica entre cada par de contextos.