Hablemos
Todos los textos
ddd arquitectura principios modelado 14 min

DDD: el libro azul de Eric Evans, sin el aire de seminario caro

Autor
Jesús E
Publicado
26 de abril de 2026

Hay libros técnicos que envejecen mal — los lees diez años después y la mitad ya no aplica. Y hay otros que envejecen como el mezcal: con el tiempo se entienden mejor. Domain-Driven Design: Tackling Complexity in the Heart of Software —el llamado libro azul— pertenece firmemente a la segunda categoría. Salió en agosto de 2003 por Addison-Wesley, tiene 560 páginas, y 23 años después la industria todavía no termina de digerirlo.

Este post no pretende ser el libro. Pretende ser la versión que te explica un colega mientras te toma un café, sin la pose de seminario caro de mil dólares al día.

Quién es Eric Evans (y por qué le hicieron caso)

Eric Evans no es un académico. Es un consultor de software que pasó los años 90 metiéndose en sistemas grandes —seguros, supply chain, banca— y notando que los proyectos fracasaban casi siempre por el mismo lugar: el equipo técnico nunca entendió bien el negocio, y el equipo de negocio nunca entendió cómo el modelo del software estaba traicionando lo que ellos sí sabían.

Fundó su consultora Domain Language, Inc. a fines de los 90s, y Domain-Driven Design es básicamente la destilación de una década de notas de proyectos reales. No es un libro de patrones de diseño OO al estilo GoF. Es un libro sobre cómo conversar con el experto del dominio y cómo dejar que esas conversaciones se vuelvan código sin perderse en la traducción.

Esa es la sutileza que mucha gente se pierde con DDD: no es una arquitectura. Es una disciplina de modelado. Las arquitecturas que la gente asocia con DDD —hexagonal, capas, event sourcing, microservicios— son consecuencias, no la cosa.

El problema que DDD intenta resolver

Si llevas algunos años en la industria, este caso te suena:

El equipo entrega un sistema “según lo pedido”. Tres meses después el negocio cambia algo trivial —“ahora también vendemos a empresas, no sólo a consumidores”— y resulta que el cambio toca 47 archivos en 6 capas. ¿Por qué? Porque el modelo del software nunca representó realmente cómo piensa el negocio: representó cómo el programador entendió la primera reunión.

Evans escribe en el prefacio una frase que vale la pena leer despacio:

“The heart of software is its ability to solve domain-related problems for its user. All other features, vital though they may be, support this basic purpose.”

(El corazón del software es su capacidad de resolver problemas de dominio para su usuario. El resto, por vital que sea, apoya ese propósito básico.)

— Eric Evans, Domain-Driven Design, prefacio (2003).

Es una declaración fuerte. Tu auth, tu cache, tu observability, tu CI/CD — son medios. El fin es el modelo del negocio. Si el modelo del negocio en tu código está roto, lo demás no te salva.

El concepto fundacional: Lenguaje Ubicuo

Si te llevas una sola idea de DDD, que sea esta. Es la que más payoff te da por unidad de esfuerzo.

Lenguaje Ubicuo (Ubiquitous Language) es la regla de que una sola palabra significa una sola cosa, en todo el equipo, en toda la documentación, en todo el código. Si el dueño del negocio dice “póliza”, el código tiene una clase Policy. No Contract, no Agreement, no InsuranceItem. Póliza.

Suena trivial. No lo es. Pasa esto todo el tiempo:

  • Negocio dice “cliente”. Programador escribe User.
  • Negocio dice “envío”. Programador escribe Order (porque “es lo mismo, ¿no?”).
  • Negocio distingue entre “cliente activo” y “cliente moroso”. Programador tiene un solo Customer con un boolean isActive.

Cada uno de esos saltos lingüísticos es un lugar donde el modelo se desconecta del negocio. Y cada desconexión es un bug futuro esperando turno.

“A project faces serious problems when its language is fractured.”

(Un proyecto enfrenta problemas serios cuando su lenguaje está fracturado.)

— Evans, capítulo 2, Communication and the Use of Language.

La regla práctica: sienta al experto del dominio con el equipo y escuchen cómo habla. Anota las palabras que usa con precisión. Esas son las clases. Esos son los métodos. Esos son los nombres en el README. Si en una reunión alguien dice una palabra rara que el experto usa pero nadie del equipo había anotado, es una señal de que la palabra debería estar en el código.

Bounded Context: la idea que cambió todo

Si Lenguaje Ubicuo es la idea más útil, Bounded Context es la más estructural — y probablemente lo que más justificó el furor de DDD en la era de microservicios.

La situación que describe es esta: en una empresa real, la palabra “cliente” no significa lo mismo en todos lados. Para el equipo de ventas, “cliente” es un prospecto con descuentos y crédito. Para el equipo de soporte, “cliente” es alguien con tickets y contratos. Para finanzas, “cliente” es un facturable con RFC y términos de pago. Tres modelos distintos de la misma palabra, todos correctos en su propio contexto.

El error clásico —el que destroza sistemas grandes— es intentar unificarlos. Hacer un solo Customer que sirva para todo, con 47 campos opcionales y reglas que dependen de quién pregunta. Eso se llama the big ball of mud, y Evans tiene un nombre técnico para ese fracaso: violación de los bounded contexts.

La solución es tan controvertida como liberadora:

Acepta que hay varios modelos. Cada uno vive en su propio contexto. La traducción entre ellos es explícita, no implícita.

Cada Bounded Context tiene:

  • Su propio Lenguaje Ubicuo (la palabra “cliente” puede significar tres cosas distintas).
  • Su propio modelo de datos.
  • Su propio equipo (ideal pero no siempre).
  • Sus propias reglas de consistencia.

Y entre contextos, hay un Context Map que documenta cómo se traducen los conceptos:

Bounded Context: Finanzas

Bounded Context: Soporte

Bounded Context: Ventas

Customer-Supplier

(Ventas crea, Soporte consume)

Conformist

(Finanzas se adapta a Ventas)

Anti-Corruption Layer

(traducción explícita)

Cliente

= prospecto

+ pipeline

+ descuentos

Cliente

= cuenta

+ tickets

+ SLA

Cliente

= facturable

+ RFC

+ términos pago

Bounded Context se introduce en la Parte IV: Strategic Design, capítulo 14 (“Maintaining Model Integrity”). No es accidente que esté tan tarde en el libro: la mayoría de los problemas con DDD vienen de equipos que aprendieron los building blocks tácticos (entities, value objects, aggregates) sin haber leído la parte estratégica donde está la verdadera medicina.

Martin Fowler escribió un artículo cortito explicando este concepto sin pedir 560 páginas. Si tienes prisa, ese es tu atajo.

Los building blocks tácticos

Esta es la parte que todo el mundo cita y que, ironicamente, es la menos importante del libro. Pero hay que conocerla.

BloqueQué esEjemplo
EntityObjeto con identidad propia que persiste a lo largo del tiempoUn Customer con id C-12345. Si cambian sus datos, sigue siendo el mismo cliente.
Value ObjectObjeto definido sólo por sus atributos, sin identidadMoney(100, "MXN"). Dos objetos con los mismos atributos son el mismo.
AggregateCluster de entities + value objects que se modifican como una unidad, con un aggregate rootOrder (root) contiene OrderLines. No tocas OrderLine directamente; pasas por Order.
RepositoryAbstracción de persistencia para obtener aggregatesOrderRepository.findById(orderId) — no sabes si por dentro hay SQL, MongoDB, o un archivo.
FactoryObjeto cuya responsabilidad es crear aggregates complejosOrderFactory.createFromCart(cart, customer) — encapsula reglas de creación.
Domain ServiceOperación del dominio que no encaja naturalmente en una sola entityTransferService.transfer(fromAccount, toAccount, amount) — toca dos cuentas, no es de ninguna.

Importante con los aggregates (porque es donde la gente más se equivoca): el aggregate root es la única puerta. Si tienes Order con OrderLines adentro, no expongas las líneas para que cualquiera las modifique. Toda mutación pasa por métodos de Order (order.addLine(...), order.cancelLine(...)). Eso es lo que mantiene las invariantes de negocio (por ejemplo: “el total de las líneas tiene que coincidir con el total de la orden”).

“An aggregate is a cluster of associated objects that we treat as a unit for the purpose of data changes.”

— Evans, capítulo 6, The Lifecycle of a Domain Object.

Una nota importante de honestidad histórica: los Domain Events no estaban en el libro original de 2003. Evans los añadió formalmente más tarde, en su Domain-Driven Design Reference (2015, PDF gratis). Cuando alguien hoy dice “DDD es event sourcing y CQRS”, está mezclando capas: el libro azul no menciona event sourcing, ni CQRS, ni microservicios. Esos son agregados posteriores que la comunidad construyó sobre la base estratégica de Evans.

Arquitectura en capas (la del libro, no la de los memes)

El libro propone una arquitectura por capas que sigue siendo el punto de partida sano para sistemas medianos:

depende sólo de abstracciones

implementa interfaces del domini

User Interface

(controllers, views, DTOs)

Application Layer

(coordina casos de uso, sin lógica de negocio)

Domain Layer

(entities, value objects, aggregates, services)

EL CORAZÓN

Infrastructure Layer

(persistencia, mensajería, integraciones)

La regla de oro: el dominio no depende de nada que no sea otro dominio. No conoce HTTP, no conoce SQL, no conoce Kafka. Si mañana migran de PostgreSQL a DynamoDB, el dominio no debería enterarse.

Si esto te suena a Hexagonal Architecture o Clean Architecture, es porque son la misma idea, redescubierta varias veces. Alistair Cockburn publicó Hexagonal en 2005, Bob Martin publicó Clean Architecture en 2012. Las tres son básicamente “el dominio en el centro, lo técnico afuera, dependencias apuntando hacia adentro”.

Donde DDD se pone serio: Strategic Design

Aquí es donde DDD deja de ser “OO bonito” y se vuelve una herramienta para organizar empresas, no sólo código. La parte IV del libro es la que más te paga si trabajas en sistemas grandes.

Context Map y patrones de relación

Cuando tienes 5+ bounded contexts, necesitas saber cómo conviven. Evans propone un catálogo de relaciones, hoy todas con nombres canónicos:

PatrónCuándo aplicarlo
Shared KernelDos equipos comparten un subset chico de modelo. Cambios requieren coordinación. Frágil — usar con cuidado.
Customer-SupplierEquipo upstream provee, equipo downstream consume. Hay relación de cliente: el upstream prioriza necesidades del downstream.
ConformistDownstream se adapta tal cual al modelo del upstream. Sin negociación. Útil cuando el upstream es legacy o externo.
Anti-Corruption Layer (ACL)Capa de traducción que protege tu modelo del modelo extranjero. La medicina contra integraciones tóxicas.
Open Host ServicePublicas un protocolo bien diseñado para muchos consumidores. APIs REST públicas, en esencia.
Published LanguageFormato compartido (XML, JSON, Avro) entre contextos para intercambio.
Separate WaysDos contextos sin integración. Sí, también es válido — a veces no integrar es la mejor decisión.

Si entras a una empresa nueva y no entiendes cómo se hablan sus sistemas, dibujar un context map en una pizarra te va a dar más insight en una hora que un mes leyendo código.

Core Domain, Supporting, Generic

Evans propone clasificar tu dominio en tres tipos —y la decisión de dónde inviertes esfuerzo se desprende de ahí:

  • Core Domain. Lo que hace única a tu empresa. La razón por la que el cliente te paga a ti y no al competidor. Aquí va tu mejor gente, tu mejor diseño, tu mejor modelo.
  • Supporting Subdomain. Necesario para el negocio pero no diferenciador. Tiene que existir, pero no tiene que ser brillante. Buen código pragmático, sin sobrediseño.
  • Generic Subdomain. Resuelve un problema universal — autenticación, facturación, envío de mails. Cómpralo. No lo escribas tú. Stripe, Auth0, SendGrid existen por una razón.

La aplicación pragmática: ¿cuántos equipos has visto escribiendo su propio sistema de auth? La mayoría. ¿Cuántos lo necesitaban? Casi ninguno. Cada hora invertida en auth es una hora que no estás invirtiendo en core domain.

Las herramientas que la comunidad agregó después

DDD no se quedó congelado en 2003. Tres herramientas de la comunidad que hoy son inseparables del DDD práctico:

EventStorming (Alberto Brandolini, ~2013)

Una técnica de modelado en pared con post-its. Reúnes al equipo + experto del dominio + post-its naranjas (eventos del dominio: “OrderPlaced”, “PaymentReceived”). En 3 horas descubres más sobre el negocio que en 3 meses de reuniones. Brandolini publicó Introducing EventStorming en Leanpub. Si tu equipo nunca lo ha hecho, agenda una sesión esta semana.

Domain Storytelling (Hofer & Schwentner, 2021)

Un primo más narrativo de EventStorming: dibujas el flujo de una historia real del dominio con flechas numeradas y actores. Stefan Hofer y Henning Schwentner publicaron el libro homónimo (Addison-Wesley, Signature Series, 2021).

CQRS (Greg Young, ~2010)

Separa el modelo de escritura (commands) del modelo de lectura (queries). Útil cuando las consultas y las mutaciones tienen requerimientos muy distintos (lecturas optimizadas, escrituras consistentes). Greg Young popularizó el término hacia 2010 con su CQRS Documents, construyendo sobre el Command-Query Separation de Bertrand Meyer (años 80). Cuidado: CQRS introduce mucha complejidad. No lo apliques de default — sólo cuando ya viste con tus ojos que necesitas la separación.

DDD en la era de microservicios

La explosión de microservicios entre 2014 y 2020 puso a DDD de moda otra vez, y por buena razón: los bounded contexts son el insumo natural para definir los límites de servicios. Si tu microservicio no coincide con un bounded context bien definido, vas a tener un sistema distribuido que se siente más bien una big ball of mud distribuida con red latencia gratis.

Regla práctica: un microservicio = un bounded context. Si no tienes el bounded context claro, no separes el servicio todavía.

Equipos que se brincan ese paso terminan con 12 microservicios que requieren ser desplegados juntos, comparten base de datos, y se llaman entre sí en cascada de 5 niveles. Eso es un monolito caro, no microservicios.

El playbook pragmático

Sin pretender que todo sistema necesita DDD completo, hay un núcleo de prácticas que siempre vale aplicar:

PrácticaCuándo
Lenguaje Ubicuo rigurosoSiempre. No cuesta. Paga desde el día uno.
Identificar bounded contextsCuando tu equipo crece de 1 a 2+ equipos, o tu sistema crece de 1 a varios módulos.
Aggregates con root claroCuando tienes invariantes de negocio que cruzan varias entities.
ACL en integraciones externasSiempre que integres con un sistema legacy o de terceros. La regla no negociable.
Core / Supporting / GenericCuando decidas dónde poner a tu mejor gente o qué construir vs. comprar.
EventStormingCada vez que entres a un dominio nuevo o que un dominio existente esté confuso.
CQRS / Event SourcingSólo cuando ya hayas dolido sin ellos. No son default.

Las dos críticas honestas a DDD

Para no escribir un evangelio, dos quejas legítimas que tiene la industria con DDD —y que vale la pena tener en mente:

1. Es caro de aplicar bien. DDD requiere acceso continuo al experto del dominio, equipos pequeños y estables, tiempo para modelar deliberadamente. Si trabajas en una agencia con rotación alta, equipos overcommiteados y dueños de producto que aparecen una vez al mes, vas a hacer DDD malo. Y DDD malo es peor que código pragmático sin DDD.

2. Mucha gente se queda en la parte táctica. Lee el libro, aprende entities, value objects y repositories, y se cree que ya hace DDD. Pero la verdadera medicina del libro está en la parte estratégica (bounded contexts, context maps, core domain). Si no lees la Parte IV, no leíste DDD. Léela primero, si tienes prisa.

La frase de Evans que vale guardar

Si tuviera que reducir 560 páginas a una sola línea, sería esta:

“The challenge is to understand the people who use the software and the world they inhabit, then build a model that reflects that understanding.”

(El reto es entender a la gente que usa el software y el mundo que habitan, y construir un modelo que refleje ese entendimiento.)

— Eric Evans, Domain-Driven Design (paráfrasis del prefacio).

Esa frase no envejece. Las tecnologías cambian; los frameworks cambian; los lenguajes cambian. Lo que no cambia es que el software sigue resolviendo problemas de gente real en mundos reales, y modelar eso bien sigue siendo el trabajo del programador serio.

Lecturas que sí valen la pena

  • Eric Evans (2003), Domain-Driven Design: Tackling Complexity in the Heart of Software, Addison-Wesley. ISBN 978-0321125217. El libro azul. 560 páginas. Lectura obligada — al menos la Parte IV.
  • Eric Evans (2015), Domain-Driven Design Reference (PDF gratis, ~50 páginas) — un compendio de definiciones, incluyendo Domain Events que se añadieron después del libro original.
  • Vaughn Vernon (2013), Implementing Domain-Driven Design, Addison-Wesley. ISBN 978-0321834577. El libro rojo. Más práctico que Evans, con código real (.NET y Java). 656 páginas.
  • Vlad Khononov (2021), Learning Domain-Driven Design, O’Reilly. La introducción moderna y compacta — si Evans te da pereza, empieza aquí.
  • Stefan Hofer & Henning Schwentner (2021), Domain Storytelling, Addison-Wesley Signature Series.
  • Alberto Brandolini, Introducing EventStorming (Leanpub, en progreso) — el método más usado para descubrir bounded contexts en equipo.
  • Abel Avram & Floyd Marinescu (2006), Domain-Driven Design Quickly (InfoQ, PDF gratis, ~104 páginas) — la versión “quick reference” del libro azul.
  • Martin Fowler, BoundedContext — el ensayo de tres páginas que muchos prefieren al capítulo 14.
  • Greg Young (2010), CQRS Documents — el documento canónico sobre CQRS.

Y si te llevas una sola idea de todo el post: el código no es el dominio. El código es un modelo del dominio. Tu trabajo no es escribir clases bonitas — es construir un modelo que represente fielmente cómo funciona el negocio. Si haces eso bien, las clases bonitas salen solas. Si lo haces mal, ningún SOLID te salva.

Devolvámosle tiempo a su equipo.

Si alguna operación de su organización le está costando horas que podrían invertirse mejor, conversémoslo.