← Volver a artículos

29 de abril de 2026

9 min de lectura

DDD pragmático para productos web

Lenguaje ubicuo, bounded contexts y límites transaccionales sin convertir el modelado del dominio en burocracia.

Read in English

DDD empieza con lenguaje, no con entidades

Muchos equipos saltan a crear `User`, `Order`, `Invoice` y creen que ya están haciendo DDD. En realidad, lo primero es acordar lenguaje. ¿Qué significa “cliente activo”? ¿Cuándo una orden está cerrada? ¿Qué diferencia hay entre invitación, miembro y colaborador? Sin ese vocabulario, el código solo replica ambigüedad.

Cuando producto, soporte y desarrollo usan palabras distintas para el mismo flujo, el modelo termina mintiendo. DDD sirve precisamente para alinear ese lenguaje con el sistema y evitar que cada capa traduzca términos a su manera.

Los bounded contexts son fronteras de cambio

Un bounded context no es una carpeta elegante. Es un límite donde un término tiene un significado concreto y consistente. “Cuenta” puede significar una organización en billing, un tenant en permisos y un perfil en onboarding. Forzar una sola definición global suele crear más fricción que orden.

En productos web, suele ser más útil pensar los contexts como zonas de cambio coordinado: billing cambia por reglas financieras, identity cambia por permisos y sesiones, publishing cambia por flujos editoriales. Si todo vive en un único modelo universal, cualquier ajuste rompe demasiado.

  • Usa un contexto cuando las reglas cambian por razones distintas.
  • Separa cuando dos equipos hablan del mismo término con intenciones diferentes.
  • No separes si solo estás repartiendo tablas sin aislar comportamiento.

Agregados pequeños y con invariantes reales

El error común es convertir cada relación de base de datos en un agregado enorme. Un agregado no es un join conceptual; es un límite de consistencia. Si una regla necesita validarse atómicamente, probablemente pertenece al mismo agregado. Si no, quizá estás metiendo de más.

Un `Workspace` puede necesitar garantizar que solo exista un owner principal. Una `Subscription` puede proteger transiciones válidas de estado. En cambio, querer actualizar media docena de colecciones porque “todo pertenece al mismo negocio” suele terminar en bloqueos, acoplamiento y latencia.

Un agregado pequeño protege invariantes, no tablas.

class Subscription {
  constructor(
    readonly id: string,
    private status: 'trialing' | 'active' | 'past_due' | 'canceled',
  ) {}

  cancel() {
    if (this.status === 'canceled') {
      throw new Error('Subscription is already canceled');
    }

    this.status = 'canceled';
  }
}

DDD útil se siente como claridad operativa

La mejor señal de que DDD está ayudando no es que aparezcan más diagramas. Es que las decisiones importantes quedan en un lugar reconocible, los nombres mejoran y el sistema deja de filtrar reglas por accidente en cualquier endpoint o componente.

Si para “hacer DDD” el equipo debe escribir más ceremonias que código útil, el proceso ya se desvió. El objetivo nunca fue romantizar el modelado; fue darle forma a un sistema que cambia seguido sin degradarse cada sprint.

Más artículos

Volver a artículos