El Disseny Dirigit pel Domini (DDD, per les seves sigles en anglès Domain-Driven Design) és un enfocament de desenvolupament de programari que situa el domini del negoci al centre de totes les decisions de disseny. En lloc de començar per la base de dades o per la tecnologia, el DDD proposa començar per comprendre en profunditat el problema que estem resolent i modelar-lo en codi de manera fidel. Aquesta lliçó estableix les bases conceptuals que necessitaràs per abordar la resta del mòdul: què és realment el DDD, com es descompon un domini, què és un model de domini i la diferència crucial entre disseny estratègic i tàctic. Comprendre aquests fonaments és essencial perquè el DDD no és una llibreria ni un framework, sinó una manera de pensar que afecta l'arquitectura completa de les teves aplicacions.
Contingut
- Què és el Disseny Dirigit pel Domini?
- Domini, subdominis i la seva classificació (nucli, suport, genèric)
- El model de domini
- Disseny estratègic enfront del disseny tàctic
- Quan aplicar el DDD (i quan no)
- Què és el Disseny Dirigit pel Domini?
El DDD va ser formalitzat per Eric Evans al seu llibre Domain-Driven Design: Tackling Complexity in the Heart of Software (2003). La seva premissa central és senzilla d'enunciar però difícil de dominar: el programari ha de reflectir el domini del negoci que automatitza.
El domini és l'esfera de coneixement i activitat al voltant de la qual gira l'aplicació. Per a una asseguradora, el domini inclou conceptes com pòlisses, primes, sinistres, cobertures o assegurats. El DDD sosté que el major valor d'una aplicació complexa no rau en la seva tecnologia, sinó en com de bé el seu codi captura les regles i el llenguatge d'aquest domini.
Els tres pilars del DDD són:
- Col·laboració estreta amb els experts del domini. Els desenvolupadors no poden modelar bé allò que no entenen. Calen converses constants amb qui coneix el negoci.
- Un llenguatge compartit i precís (el Llenguatge Ubic, que veurem a la lliçó 06-02) usat tant en parlar com en el codi.
- Un model de domini explícit que evoluciona a mesura que millora la comprensió del problema.
El DDD no és codi primer ni base de dades primer: és model primer.
- Domini, subdominis i la seva classificació
Un domini gran rarament és uniforme. Es descompon en subdominis, àrees més petites i cohesionades del negoci. Identificar i classificar els subdominis és un dels primers exercicis estratègics del DDD, perquè ens indica on invertir esforç i on no.
Existeixen tres tipus de subdominis:
| Tipus de subdomini | Descripció | Estratègia recomanada | Exemple (asseguradora) |
|---|---|---|---|
| Nucli (Core) | Allò que diferencia el negoci de la competència. És la raó de ser de l'empresa. | Invertir el millor talent i aplicar DDD en profunditat. Construir-lo a mida. | Càlcul i tarifació de primes, avaluació de riscos |
| Suport (Supporting) | Necessari per al negoci però no diferenciador. | Desenvolupament més simple, es pot subcontractar. DDD lleuger. | Gestió documental de pòlisses |
| Genèric (Generic) | Problema comú a molts negocis, ja resolt pel mercat. | Comprar una solució comercial o usar un servei existent. No reinventar. | Autenticació, enviament de correus, facturació estàndard |
La clau pràctica és aquesta: no tot mereix el mateix esforç. Aplicar un modelatge ric de DDD a un subdomini genèric (per exemple, l'enviament d'emails) és malgastar recursos. L'esforç de modelatge s'ha de concentrar en el subdomini nucli.
graph TD
D[Domini: Asseguradora] --> C[Subdomini Nucli:<br/>Tarifació i Riscos]
D --> S1[Subdomini Suport:<br/>Gestió Documental]
D --> S2[Subdomini Suport:<br/>Atenció al Client]
D --> G1[Subdomini Genèric:<br/>Autenticació]
D --> G2[Subdomini Genèric:<br/>Notificacions Email]En aquest diagrama Mermaid de tipus graph TD (top-down, de dalt a baix):
- El node
Drepresenta el domini complet de l'asseguradora. - Les fletxes
-->indiquen la descomposició en subdominis. - Es distingeixen visualment el subdomini nucli (on competeix l'empresa) dels de suport i els genèrics.
L'objectiu d'aquest mapa és comunicatiu: ajuda l'organització a posar-se d'acord sobre on rau el veritable valor.
- El model de domini
Un model de domini és una abstracció rigorosa i selectiva del coneixement del domini. No és un diagrama de base de dades ni un diagrama de classes UML qualsevol: és un sistema de conceptes, regles i comportaments que captura com funciona el negoci.
Característiques d'un bon model de domini:
- És comportament, no només dades. Un model anèmic que només té getters i setters no és DDD. El model ha de contenir les regles del negoci.
- Usa el llenguatge del negoci. Les classes i mètodes es diuen tal com els experts del domini anomenen les coses.
- Evoluciona. A mesura que s'aprèn més del domini, el model es refina.
Comparem un model anèmic amb un model ric:
// MODEL ANÈMIC (a evitar): només dades, sense regles
public class Poliza {
private BigDecimal prima;
private boolean activa;
public BigDecimal getPrima() { return prima; }
public void setPrima(BigDecimal prima) { this.prima = prima; }
public boolean isActiva() { return activa; }
public void setActiva(boolean activa) { this.activa = activa; }
}A l'exemple anterior:
- La classe
Polizaés un mer contenidor de dades. - Qualsevol codi extern pot modificar
primaoactivasense cap restricció. - Les regles del negoci (quan es pot activar una pòlissa? La prima pot ser negativa?) viuen disperses en serveis externs, no al model. Això es coneix com a Anemic Domain Model i és un antipatró en DDD.
// MODEL RIC (DDD): les dades estan protegides i el comportament viu aquí
public class Poliza {
private final BigDecimal prima;
private EstadoPoliza estado;
public Poliza(BigDecimal prima) {
if (prima == null || prima.compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("La prima ha de ser positiva");
}
this.prima = prima;
this.estado = EstadoPoliza.BORRADOR;
}
public void activar() {
if (this.estado != EstadoPoliza.BORRADOR) {
throw new IllegalStateException("Només s'activa una pòlissa en esborrany");
}
this.estado = EstadoPoliza.ACTIVA;
}
}Aquí el canvi és profund:
- El constructor valida que la prima sigui positiva: és impossible crear una
Polizainvàlida. - El camp
primaésfinal: no es pot canviar després de la creació (immutabilitat parcial). - El mètode
activar()encapsula la regla de negoci: només una pòlissa en estatBORRADORes pot activar. La regla viu dins del model, no fora. - L'estat només canvia a través de mètodes amb noms del negoci, no de setters genèrics.
Aquest és el cor del DDD: el model protegeix les seves pròpies regles (invariants).
- Disseny estratègic enfront del disseny tàctic
El DDD opera en dos nivells complementaris. Confondre'ls és un dels errors més habituals en començar.
| Aspecte | Disseny estratègic | Disseny tàctic |
|---|---|---|
| Pregunta que respon | Com dividim el domini en parts? | Com modelem cada part en codi? |
| Nivell | Arquitectura, organització, equips | Classes, objectes, patrons |
| Conceptes clau | Subdominis, Bounded Contexts, Llenguatge Ubic, Context Mapping | Entitats, Value Objects, Agregats, Repositoris, Serveis i Esdeveniments de Domini |
| Audiència | Arquitectes, líders, negoci | Desenvolupadors |
| Es cobreix a | Lliçons 06-02 i 06-04 | Lliçó 06-03 |
El disseny estratègic traça el mapa: decideix els límits, els llenguatges i com es relacionen les diferents parts del sistema. El disseny tàctic proporciona els patrons d'implementació dins de cada part. L'estratègic és més important: un bon disseny tàctic dins d'uns límits mal traçats continua produint un mal sistema.
- Quan aplicar el DDD (i quan no)
El DDD té un cost: requereix temps, col·laboració amb experts i una corba d'aprenentatge. No és gratis i no sempre compensa.
Aplica DDD quan:
- El domini és complex (moltes regles de negoci, no només CRUD).
- El projecte és estratègic i de llarga vida.
- Tens accés a experts del domini disposats a col·laborar.
Evita o redueix el DDD quan:
- L'aplicació és un CRUD simple amb prou feines regles.
- És un prototip d'un sol ús o una prova de concepte.
- El subdomini és genèric i existeix una solució comercial.
Regla pràctica: la complexitat de l'enfocament ha de ser proporcional a la complexitat del domini.
Errors Comuns i Consells
- Confondre el DDD amb una arquitectura concreta. El DDD no obliga a usar microserveis, ni hexagonal, ni event sourcing. Són enfocaments que combinen bé, però el DDD és independent d'ells.
- Començar pels patrons tàctics. Molts equips salten directament a "fer agregats i repositoris" sense haver fet la feina estratègica. El resultat són límits mal posats. Comença sempre per l'estratègic.
- Crear models anèmics. Si les teves classes de domini només tenen getters/setters, no estàs fent DDD, estàs fent procediments disfressats d'objectes.
- Aplicar DDD a tot. Reserva l'esforç per al subdomini nucli. Per al genèric, compra o reutilitza.
- Consell: parla amb els experts del domini en el seu llenguatge i escolta els substantius i verbs que usen: són les pistes del teu model.
Exercicis
Exercici 1. Per a una plataforma de comerç electrònic, identifica com a mínim un subdomini de cada tipus (nucli, suport, genèric) i justifica'n la classificació.
Exercici 2. Revisa la classe Poliza anèmica de l'apartat 3. Identifica quines regles de negoci queden sense protegir i proposa com a mínim dos mètodes de comportament que haurien d'existir en un model ric.
Exercici 3. Indica si aplicaries DDD complet, DDD lleuger o cap DDD a cada cas, justificant la resposta: (a) una eina interna per registrar les vacances dels empleats; (b) el motor de càlcul de primes d'una asseguradora; (c) el mòdul d'enviament d'SMS de notificació.
Solucions
Solució 1. Un exemple raonable:
- Nucli: el motor de recomanacions de productes, si és el que diferencia la plataforma de la competència.
- Suport: la gestió del catàleg de productes (necessària, però no diferenciadora enfront de competidors).
- Genèric: la passarel·la de pagaments (problema resolt per serveis com Stripe o Redsys; no es reinventa).
Solució 2. Regles sense protegir: la prima pot ser nul·la o negativa; l'estat activa es pot canviar a qualsevol valor sense control de transicions vàlides. Mètodes de comportament proposats: un constructor que validi la prima (com al model ric), i mètodes activar() i cancelar() que controlin les transicions d'estat permeses en lloc d'un setActiva(boolean).
Solució 3. (a) Cap DDD o molt lleuger: és un CRUD simple amb poques regles. (b) DDD complet: és el subdomini nucli, complex i estratègic. (c) Cap DDD: subdomini genèric; convé usar un servei o llibreria existent.
Conclusió
En aquesta lliçó hem establert els fonaments del Disseny Dirigit pel Domini: hem vist que el DDD posa el domini del negoci al centre, que un domini es descompon en subdominis nucli, de suport i genèrics —cadascun amb la seva estratègia—, que el model de domini ha de ser ric en comportament i no un mer contenidor de dades, i que el DDD opera en dos nivells, estratègic i tàctic. També hem après a jutjar quan val la pena aplicar-lo.
A partir d'aquí aprofundirem en cada nivell. A la lliçó següent, "Disseny Estratègic: Bounded Contexts i Llenguatge Ubic", abordarem com traçar els límits del model i com construir el llenguatge compartit que manté la coherència entre negoci i codi.
Curs d'Arquitectura d'Aplicacions
Mòdul 1: Fonaments de l'Arquitectura d'Aplicacions
- Què és l'Arquitectura d'Aplicacions?
- El Rol de l'Arquitecte de Programari
- Atributs de Qualitat i Requisits No Funcionals
- Decisions Arquitectòniques i Compromisos (Trade-offs)
- Documentació d'Arquitectura: Vistes i el Model C4
Mòdul 2: Principis i Tàctiques de Disseny
- Acoblament, Cohesió i Separació de Responsabilitats
- Principis SOLID Aplicats a l'Arquitectura
- DRY, KISS, YAGNI i Altres Principis de Disseny
- Tàctiques Arquitectòniques per als Atributs de Qualitat
- Gestió del Deute Tècnic
Mòdul 3: Estils i Patrons Arquitectònics
- Arquitectura Monolítica
- Arquitectura en Capes (N-Tier)
- Arquitectura Client-Servidor
- Arquitectura Hexagonal (Ports i Adaptadors)
- Arquitectura Neta i Ceba (Clean & Onion)
Mòdul 4: Arquitectures Distribuïdes i Microserveis
- Introducció als Sistemes Distribuïts
- Arquitectura de Microserveis
- Descomposició de Serveis i Bounded Contexts
- API Gateway, Service Discovery i Comunicació entre Serveis
- Patrons de Resiliència: Circuit Breaker, Retry i Bulkhead
- El Teorema CAP i la Consistència de Dades
Mòdul 5: Arquitectures Dirigides per Esdeveniments i Missatgeria
- Fonaments de l'Arquitectura Orientada a Esdeveniments
- Missatgeria Asíncrona: Cues i Brokers
- Patrons d'Esdeveniments: Event Sourcing i CQRS
- Gestió de Transaccions Distribuïdes: Patró Saga
- Streaming de Dades en Temps Real
Mòdul 6: Disseny Dirigit pel Domini (DDD)
- Conceptes Fonamentals del DDD
- Disseny Estratègic: Bounded Contexts i Llenguatge Ubic
- Disseny Tàctic: Entitats, Agregats i Repositoris
- Mapatge de Contextos (Context Mapping)
Mòdul 7: Dades i Persistència
- Estratègies de Persistència: SQL vs NoSQL
- Patrons d'Accés a Dades: Repository, Unit of Work i DAO
- Base de Dades per Servei i Gestió de Dades Distribuïdes
- Cau i Estratègies d'Invalidació
Mòdul 8: Arquitectura al Núvol i Desplegament
- Fonaments del Cloud Computing (IaaS, PaaS, SaaS)
- Contenidors i Orquestració amb Docker i Kubernetes
- Arquitectura Serverless
- Patrons de Disseny Cloud-Native
- Infraestructura com a Codi (IaC)
Mòdul 9: Qualitat, Seguretat i Observabilitat
- Escalabilitat: Horitzontal vs Vertical i Balanceig de Càrrega
- Alta Disponibilitat i Tolerància a Fallades
- Seguretat per Disseny i Autenticació/Autorització
- Observabilitat: Logging, Mètriques i Traçabilitat
- Rendiment i Proves de Càrrega
