DDD en frontend: cuándo Domain-Driven Design tiene sentido | POLPROG Ir al contenido

DDD en frontend: cuándo Domain-Driven Design tiene sentido

Domain-Driven Design no es una convención de carpetas ni una técnica reservada al backend. Su objetivo es hacer manejables los dominios de negocio complejos mediante un lenguaje compartido, modelos explícitos y límites claros de contexto. En frontend, DDD puede aportar mucho valor en aplicaciones de producto grandes, pero también puede convertirse en sobrearquitectura. La clave es detectar dónde el cliente contiene complejidad de dominio real y dónde actúa principalmente como capa de presentación.

Publicado Escrito por Tiempo de lectura 9 min de lectura

Domain-Driven Design no es una convención de carpetas ni una técnica reservada al backend. Su objetivo es hacer manejables los dominios de negocio complejos mediante un lenguaje compartido, modelos explícitos y límites claros de contexto. En frontend, DDD puede aportar mucho valor en aplicaciones de producto grandes, pero también puede convertirse en sobrearquitectura. La clave es detectar dónde el cliente contiene complejidad de dominio real y dónde actúa principalmente como capa de presentación.

En esta página
  1. 1DDD no empieza con una carpeta `domain`
  2. 2DDD estratégico y DDD táctico operan en niveles distintos
  3. 3Un Bounded Context no es una capa técnica
  4. 4Cuándo DDD en frontend tiene sentido
  5. 5Cuándo DDD se convierte en sobrearquitectura
  6. 6Ubiquitous Language también debe verse en el código de UI
  7. 7Organiza un frontend grande por dominios, no solo por tipos de archivo
  8. 8Separa comportamiento de presentación y comportamiento de dominio
  9. 9Capas prácticas dentro de un contexto frontend
  10. 10El modelo de API y el modelo de dominio frontend no tienen que ser iguales
  11. 11Entities, Value Objects y Aggregates: úsalos selectivamente
  12. 12El estado de UI no es lo mismo que el estado de dominio
  13. 13Los límites deben aplicarse, no solo documentarse
  14. 14Frontend y backend pueden compartir un dominio sin compartir un modelo idéntico
  15. 15La testabilidad es una de las razones más fuertes para aislar la lógica de dominio
  16. 16Cómo introducir DDD en un frontend existente sin un gran rewrite

DDD no empieza con una carpeta `domain`

Eric Evans presenta DDD como un conjunto de patrones y definiciones para trabajar con modelos de dominio, mientras Martin Fowler pone el foco en modelar dominios complejos y desarrollar un lenguaje compartido entre desarrolladores y expertos de negocio. [1][2][4]

Por tanto, una estructura `domain/application/infrastructure` no convierte por sí sola una aplicación en DDD. Puede haber carpetas perfectamente nombradas y seguir trabajando solo con DTO y lógica procedural. También puede aplicarse DDD estratégico sin una estructura canónica por capas.

DDD estratégico y DDD táctico operan en niveles distintos

El DDD estratégico trata la división de un dominio amplio en subdominios y Bounded Contexts y sus relaciones. Microsoft describe el análisis de dominio como la identificación de subdominios y contextos, y Fowler sitúa Bounded Context como patrón central del diseño estratégico. [3][7]

El DDD táctico trabaja dentro de un contexto concreto e incluye Entities, Value Objects, Aggregates y Domain Services. Microsoft separa explícitamente el análisis estratégico del modelado táctico. [8]

En frontend suele ser mejor comenzar por el nivel estratégico y decidir después qué contextos necesitan realmente un modelo táctico rico.

Un Bounded Context no es una capa técnica

Fowler describe un Bounded Context como una frontera en la que un modelo permanece coherente y sus términos tienen significado no ambiguo. Un mismo concepto, como `Customer` o `Product`, puede tener significados distintos en diferentes contextos. [3]

Por eso `frontend`, `backend`, `React app`, `route` o `micro-frontend` no son automáticamente Bounded Contexts. Los límites nacen del modelo y del lenguaje del dominio, no de la tecnología. Guías prácticas de DDD en frontend hacen la misma advertencia. [15][16]

Cuándo DDD en frontend tiene sentido

SeñalDirecciónPor qué
Muchas reglas de negocio cambiantesDDDUn modelo de dominio evita dispersar las reglas
Los mismos conceptos significan cosas distintas según el áreaDDDBounded Contexts permiten varios modelos coherentes
Colaboran varios equipos y expertos de dominioDDDUbiquitous Language reduce ambigüedad
CRUD simple y formulariosModularidad más simpleEl coste de DDD táctico puede superar el beneficio
El frontend refleja principalmente una APIModularidad más simpleHay poca lógica de dominio propia del cliente
Aplicación pequeña con un dominio coherenteModularidad más simpleCapas y límites adicionales pueden aportar poco valor

La señal más clara son reglas de negocio complejas y cambiantes visibles también en el cliente: configuradores, procesos de varios pasos, pricing, permisos, transiciones de estado, workflows o modelos distintos del mismo concepto según el área del producto.

DDD también aporta valor cuando varios equipos trabajan en un producto grande y las mismas palabras significan cosas distintas en distintas áreas. Bounded Contexts existen precisamente para mantener varios modelos coherentes. [3]

DDD Crew recomienda comprender primero el dominio, identificar subdominios estratégicamente importantes, definir después las responsabilidades de los contextos y solo entonces codificar el modelo. [10]

Cuándo DDD se convierte en sobrearquitectura

Si el frontend se limita principalmente a obtener datos, mostrarlos, editar formularios y enviar comandos CRUD sencillos sin reglas de negocio relevantes en el cliente, el conjunto completo de patrones tácticos DDD rara vez resuelve un problema real.

Microsoft indica expresamente que para un contexto CRUD simple un modelo de datos anémico puede ser suficiente y que patrones DDD más complejos no siempre compensan. Un modelo rico resulta más útil cuando existen muchas reglas de negocio cambiantes. [9]

El mismo criterio debería usarse en frontend: la sofisticación arquitectónica debe corresponder a la complejidad del dominio, no a la ambición técnica del equipo.

Ubiquitous Language también debe verse en el código de UI

Ubiquitous Language es un lenguaje común y riguroso construido por desarrolladores y expertos de dominio alrededor del modelo. Fowler subraya que debe evolucionar a medida que el equipo entiende mejor el dominio. [4]

En frontend, los nombres de casos de uso, acciones, tipos, módulos, pantallas y estados deberían usar vocabulario de negocio cuando expresan comportamiento de dominio.

Si negocio habla de `approveApplication` pero el código usa `setFlag2` o `handleData`, el código deja de funcionar como representación clara del lenguaje del dominio.

Organiza un frontend grande por dominios, no solo por tipos de archivo

Fowler señala que una estructura superior `view/model/data` puede bastar en sistemas pequeños, pero al crecer suele ser mejor dividir el nivel superior en módulos orientados por dominio que contengan internamente sus propias capas. [5]

La documentación actual de Nx sigue un enfoque similar: las carpetas pueden convertirse en límites de ownership por dominio y dentro de cada dominio las bibliotecas pueden clasificarse como `feature`, `ui`, `data-access` y `util`. [12]

Una estructura práctica puede ser `libs/orders/...`, `libs/billing/...`, `libs/identity/...` en lugar de un árbol global `components/`, `services/`, `models/`.

Separa comportamiento de presentación y comportamiento de dominio

Fowler describe la separación entre presentación, lógica de dominio y acceso a datos como una forma eficaz de modularización. También señala que la UI suele ser más difícil de probar, por lo que mantener lógica de dominio fuera de la presentación mejora la testabilidad. [5][6]

Un componente frontend debería centrarse en renderizar, manejar eventos de UI y delegar operaciones. Reglas como si un pedido puede cancelarse, cómo calcular un descuento o qué transición de estado es válida deberían vivir fuera de JSX, plantillas o clases de componente.

Esto no prohíbe la lógica de presentación. Validación de vista, visibilidad, foco local o animación no son lo mismo que reglas de negocio.

Capas prácticas dentro de un contexto frontend

CapaResponsabilidadEjemplos
presentation / uiRenderizado y comportamiento de interfazcomponents, routes, view state
applicationCoordinación de casos de usocommands, use cases, orchestration
domainReglas, conceptos e invariantes de dominioentities, value objects, policies
infrastructure / data-accessIntegraciones técnicasHTTP, storage, SDKs, mappers

DDD no impone una estructura de carpetas concreta. Separar `presentation`, `application`, `domain` e `infrastructure` es una interpretación práctica de la separación de responsabilidades, no un requisito formal de Evans. [1][5]

La capa domain puede contener reglas, conceptos y comportamiento independientes del framework; application coordina casos de uso; infrastructure adapta HTTP, storage y SDK externos; presentation contiene componentes, routing y estado puramente visual.

El modelo de API y el modelo de dominio frontend no tienen que ser iguales

Un Bounded Context puede tener su propio modelo de un concepto y distintos contextos pueden mapear entre representaciones diferentes. Fowler usa `Customer` y `Product` como ejemplos habituales de términos con significados distintos según el contexto. [3]

Por ello, un DTO de backend no tiene que llegar directamente a todos los componentes. Un mapper o adapter puede convertir el contrato de transporte al modelo que utiliza un contexto frontend.

Esta frontera aporta más valor cuando una API sirve a varios clientes, es legacy, combina varios dominios o evoluciona de forma independiente. Para un endpoint CRUD simple, una capa adicional puede sobrar.

Entities, Value Objects y Aggregates: úsalos selectivamente

DDD distingue conceptos como Entities, Value Objects, Services y Aggregates. Fowler los destaca como parte del vocabulario de Evans y Microsoft describe los agregados como un patrón táctico para mantener la coherencia del modelo. [2][8]

El frontend no debería copiar el modelo del backend uno a uno solo para tener las mismas clases. Un Value Object puede ser útil para `Money`, `DateRange` o `Email` si protege invariantes reales. Un Aggregate tiene sentido si el cliente necesita garantizar reglas de coherencia del modelo.

Si un tipo es solo datos para mostrar una tabla, un tipo TypeScript simple puede ser mejor que Entity, Factory, Repository y Service.

El estado de UI no es lo mismo que el estado de dominio

React trata la organización del estado como un problema de diseño y recomienda evitar estado redundante o duplicado. Es una buena base técnica, pero reducers, stores o signals no crean por sí mismos un modelo de dominio. [14]

Estado como `isModalOpen`, pestaña activa o posición de scroll pertenece a presentación. El ciclo de vida de un pedido, transiciones permitidas o reglas de un configurador pueden pertenecer al dominio.

Separar ambas categorías evita stores globales que mezclan datos del servidor, comportamiento de negocio y detalles de interfaz.

Los límites deben aplicarse, no solo documentarse

Nx permite definir tags de proyecto y restricciones declarativas de dependencias, por ejemplo para bloquear imports entre scopes o tipos de biblioteca. `@nx/enforce-module-boundaries` puede verificar imports durante lint. [11]

Nx también admite varias dimensiones de tags, lo que permite modelar por separado `scope`, tipo de biblioteca, estabilidad o separación client/server. [13]

Así, decisiones de DDD pueden convertirse en reglas de CI: `billing` no importa internos de `identity`, `ui` no depende de `data-access` y `domain` permanece independiente del framework.

Frontend y backend pueden compartir un dominio sin compartir un modelo idéntico

Un Bounded Context es una frontera de modelo y lenguaje, por lo que no debería dibujarse automáticamente sobre la frontera de red entre navegador y servidor. Guías prácticas de DDD frontend destacan que los contextos pueden atravesar capas técnicas y ser implementados conjuntamente por frontend y backend. [15][16]

La representación en cliente puede ser distinta de la representación en servidor debido a necesidades diferentes de interacción, estado local y presentación. Lo importante es conservar la semántica y mapear explícitamente, no copiar clases.

Tampoco debe crearse un micro-frontend únicamente porque exista un Bounded Context. La frontera de dominio y la frontera de despliegue son decisiones distintas.

La testabilidad es una de las razones más fuertes para aislar la lógica de dominio

Fowler cita la testabilidad como beneficio de separar presentación y dominio. La lógica fuera de la UI puede probarse sin renderizar componentes ni depender de detalles de interfaz. [5][6]

En frontend esto permite pruebas rápidas de reglas, Value Objects, casos de uso y transiciones de estado como TypeScript o JavaScript normal. Las pruebas de componentes siguen siendo necesarias, pero no tienen que ser el único lugar donde validar reglas de negocio.

Una señal de alarma es que cada cambio de regla exija montar un componente completo y simular router, store, HTTP y APIs del navegador.

Cómo introducir DDD en un frontend existente sin un gran rewrite

DDD Crew propone un proceso iterativo: comprender el dominio, identificar subdominios importantes, definir responsabilidades de Bounded Contexts y después codificar el modelo. [10]

En un frontend existente es más seguro elegir un área problemática, nombrar su lenguaje, establecer su límite, separar presentación de reglas, definir la API pública del módulo y migrar después otras funciones.

No es necesario migrar toda la aplicación. DDD puede aplicarse donde la complejidad de negocio compensa el coste de modelado y dejar las áreas simples como módulos de funcionalidad más ligeros.

  • Empieza por un problema de negocio, no por las carpetas.
  • Identifica términos, reglas y conceptos ambiguos.
  • Define un Bounded Context y su contrato público.
  • Separa reglas de dominio de componentes y DTO de transporte.
  • Añade solo patrones tácticos que resuelvan complejidad concreta.
  • Convierte los límites en reglas de lint o CI.
  • Mide dependencias, ciclos, regresiones y coste de cambios transversales.
  • No migres CRUD simples solo por simetría arquitectónica.

DDD en frontend tiene sentido cuando el cliente forma parte de un producto complejo y no es solo un renderizador de datos. El mayor retorno suele venir del DDD estratégico: lenguaje común, límites de contexto y fronteras modulares aplicadas de verdad. Los patrones tácticos deberían añadirse únicamente donde existan reglas, invariantes y comportamiento que justifiquen un modelo más rico. Si la aplicación es principalmente CRUD, formularios y representación directa de API, una buena modularidad y separación entre presentación y datos suele aportar más que un DDD completo.

DDD Domain-Driven Design Frontend Architecture Software Architecture Bounded Context Ubiquitous Language TypeScript Nx React Angular

Preguntas frecuentes

¿Tiene sentido DDD en frontend?

Sí, cuando el frontend participa en un dominio complejo y se beneficia de límites explícitos, lenguaje compartido o reglas de negocio en cliente. DDD no es exclusivo del backend. [1][2][15]

¿Todo frontend debería usar DDD?

No. Para aplicaciones CRUD simples, DDD táctico completo puede ser innecesario. Microsoft indica expresamente que un contexto CRUD simple no siempre justifica un modelo rico. [9]

¿El frontend es un Bounded Context separado?

No automáticamente. Un Bounded Context es una frontera de modelo y lenguaje coherentes, no una frontera tecnológica. [3][16]

¿Cada Bounded Context debería convertirse en micro-frontend?

No. Una frontera de dominio no exige despliegue separado. La arquitectura micro-frontend es otra decisión. [3][15]

¿Necesito una carpeta domain?

No. DDD no prescribe estructura de directorios obligatoria. Una carpeta puede ayudar, pero no crea por sí sola un modelo de dominio. [1][5]

¿Dónde debe vivir la lógica de negocio en frontend?

Fuera de la presentación pura, en un modelo explícito o capa de casos de uso del contexto. Fowler recomienda separar presentación y lógica de dominio. [5][6]

¿Puede un DTO de API ser el modelo de dominio?

En un caso trivial puede, pero no tiene por qué. Distintos contextos pueden modelar el mismo concepto de forma diferente, por lo que mapear puede ser apropiado. [3]

¿Tiene sentido Repository en frontend?

Solo si resuelve un problema real de abstracción del acceso al modelo. Para obtener datos de forma simple, una capa Repository adicional puede sobrar. [1][9]

¿Redux, NgRx, Zustand o Signals forman parte de DDD?

No. Son mecanismos de gestión de estado. Pueden contener estado de dominio, pero no definen modelo, lenguaje ni Bounded Context. [14]

¿El modelo de dominio frontend debe ser idéntico al backend?

No. Debe conservar la semántica correcta, pero puede adaptar la representación a las necesidades del cliente. [3]

¿Cómo aplicar límites de dominio en un monorepo?

Nx puede usar tags y @nx/enforce-module-boundaries para bloquear automáticamente dependencias no permitidas. [11][13]

¿Por dónde empezar en una aplicación existente?

Por un área de negocio compleja: entender su lenguaje, reglas y frontera. DDD Crew recomienda avanzar de forma iterativa desde el dominio hasta los contextos y el código. [10]

Fuentes y referencias

  1. Eric Evans, DDD Reference12345
  2. Martin Fowler, Domain Driven Design123
  3. Martin Fowler, Bounded Context12345678
  4. Martin Fowler, Ubiquitous Language12
  5. Martin Fowler, Presentation Domain Data Layering123456
  6. Martin Fowler, Presentation Domain Separation123
  7. Microsoft Azure Architecture Center, Use Domain Analysis to Model Microservices
  8. Microsoft Azure Architecture Center, Use Tactical DDD to Design Microservices12
  9. Microsoft .NET, Design a microservice domain model123
  10. DDD Crew, DDD Starter Modelling Process123
  11. Nx, Enforce Module Boundaries12
  12. Nx, Monorepo Folder Structure
  13. Nx, Tag in Multiple Dimensions12
  14. React, Managing State12
  15. ANGULARarchitects, DDD in Angular & Frontend Architecture1234
  16. Tomasz Ducin, Your Frontend itself is NOT a Bounded Context123

¿Te ha resultado útil?

Recibe nuevos artículos por email

Un correo breve por cada nuevo artículo de la base de conocimiento. Sin spam, te das de baja con un clic.

Solo usamos tu email para enviar nuevos artículos. Sin compartir con terceros.

Volver a la base de conocimiento