<!--
rating: ⭐️⭐️⭐️ // 1 to 3 stars
date: 2023 // when started reading
read: 2023 // when finished reading
status: undefined, backlog, to read, reading, completed, stopped
-->

# Domain Driven Design Distilled
by [[{{author}}]]
## Summary
<!-- No more than a couple paragraphs summarizing this BOOK -->
{{description}}
## Table of Contents
<!--Link to table of contents (TOC) -->
-
## Notes
### Capítol 1 : DDD for Me
Els conceptes principals són els següents:
- **Objectiu de DDD**
DDD és un conjunt d’eines per dissenyar i implementar software que aporti alt valor tant a nivell estratègic com tàctic. L’enfocament principal és alinear el model de software amb les necessitats i competències clau del negoci, de manera que el software esdevingui un avantatge competitiu .
- **Strategic Design**
Són les eines que ajuden a delimitar i organitzar el domini global de l’aplicació. Inclou conceptes com **Bounded Contexts** (límits on un model és vàlid), **Subdomains** (subparts del domini) i **Context Maps** (comunicació i integració entre contexts) .
- **Tactical Design**
Conjunt de patrons per implementar detalladament el model dins de cada Bounded Context: **Entitats**, **Value Objects**, **Aggregates**, **Repositoris**, **Domain Services**, **Domain Events** i **Factories**. Aquests patrons garanteixen una arquitectura coherent i mantenible .
- **“Task-board shuffle”**
Pràctica on l’equip només mou “stickies” sense pensar el disseny, generant **Big Balls of Mud** (pocs models i molta complexitat) i elevats costos de manteniment per falta de disseny conscienciat .
- **Disseny efectiu vs. disseny bo/malament**
_No existeix “sense disseny”_, sempre es modelitza d’alguna manera. L’alternativa és fer-ho **efectivament**, entenent què ha de fer l’organització per destacar i traduir-ho en un model de software que reflecteixi aquestes prioritats domain-driven-design-di…domain-driven-design-di….
- **Col·laboració i llenguatge ubiqüitari**
Imprescindible treballar junts desenvolupadors i **Domain Experts** per crear una **Ubiquitous Language** (terminologia compartida) que sigui usada tant en el codi com en la conversa diària, evitant malentesos i fractures entre negoci i implementació domain-driven-design-di…domain-driven-design-di….
- **Procés d’aprenentatge i refinament**
DDD promou un bucle continu de descoberta mitjançant converses i experiments (per exemple, **Event Storming**), accelerant la comprensió del negoci i la qualitat del model a mesura que l’equip avança domain-driven-design-di…domain-driven-design-di….
- **Beneficis generals**
— Models més alineats amb el negoci
— Equips més eficients i amb menys dependències
— Facilita l’escalabilitat i mantenibilitat del software
— Permet triar l’arquitectura més adequada (in-house, núvol, microserveis…)
### Capítol 2 : Strategic Design with Bounded Contexts and the Ubiquitous Language
els conceptes principals i una breu explicació de cadascun:
- **Bounded Context**
Límit semàntic explícit en què cada element del model té un significat únic i coherent. Dins d’un Bounded Context hi haurà un únic model (i, idealment, un sol Subdomain) implementat en artefactes separats de codi i esquema de dades .
- **Problem Space vs Solution Space**
- _Problem Space_: anàlisi estratègic d’alt nivell (drivers, riscos, Context Maps) abans d’implementar res.
- _Solution Space_: on efectivament es codifica el Core Domain dins del Bounded Context, incloent-hi integracions amb altres contexts .
- **Ubiquitous Language**
Llenguatge compartit i rigorós desenvolupat conjuntament per desenvolupadors i Domain Experts, que serveix tant per parlar del domini com per implementar-lo en codi. Ha de ser estricte, precís i reflectir només els conceptes “in context” .
- **Domain Experts i Business Drivers**
Cal integrar experts del negoci des del principi per respondre a “Què és realment core?” i filtrar els conceptes que formaran part del Core Domain. Sense aquest enfocament, el model ràpidament es dispersa .
- **Eines Estratègiques Fonamentals**
Les dues palanques clau per evitar models monolítics són el Bounded Context i el Ubiquitous Language:
1. Definir què és _core_ i separar-ho de la resta.
2. Capturar els termes “in context” perquè siguin la base del llenguatge equip–codi .
- **Challenge and Unify**
Mitjançant tallers col·laboratius (per exemple, Event Storming), el equip qüestiona assumptes i unifica mentalitats, assegurant que tothom entén els mateixos conceptes i evita fissures en el model domain-driven-design-di…domain-driven-design-di….
- **Developing a Ubiquitous Language**
No només noms; es tracta de definir escenaris concrets de funcionament del domini (quins fets succeeixen, què ha de fer cada component) per fer el llenguatge més ric i alineat amb la realitat de negoci domain-driven-design-di…domain-driven-design-di….
- **Arquitectura de Contextos**
Cada Bounded Context ha de tenir el seu propi equip, repositori de codi i esquema de base de dades. Això elimina dependències imprevistes i reforça la propietat clara del model domain-driven-design-di…domain-driven-design-di….
- **Resum i Beneficis**
- Reducció de complexitat mitjançant fronteres semàntiques clares.
- Models alineats amb les necessitats estratègiques.
- Equip més efectiu i amb menys dependències.
- Preparació per a integracions controlades amb altres contexts.
Amb aquests punts claus, podràs començar a aplicar el **Strategic Design** de DDD definint límits de context, filtrant el nucli de negoci i establint un llenguatge compartit abans de passar al nivell tàctic.
### Capítol 3: Strategic Design With Subdomains
Els punts més importants del capítol són:
- **Què és un Subdomain?**
Un Subdomain és una sub-part lògica del teu domini de negoci, amb un conjunt coherent de conceptes i regles. Normalment un Subdomain es converteix en un model de domini propi, amb els seus Domain Experts que en coneixen els detalls i amb la seva Ubiquitous Language particular .
- **Tipus de Subdomains**
1. **Core Domain**: àrea on l’empresa inverteix més recursos i que la distingeix de la competència. S’hi crea un model estratègic i es destinen els millors equips per refinar la Ubiquitous Language.
2. **Supporting Subdomain**: requereix desenvolupament a mida però sense l’impacte ni la inversió del Core. Sovint es pot externalitzar per no malbaratar esforç estratègic.
3. **Generic Subdomain**: funcionalitats genèriques (p. ex. autenticació, pagaments) que es poden adquirir “off the shelf” o desenvolupar amb equip menys especialitzat. Cal no confondre-les amb el Core .
- **Gestionant la complexitat**
Els sistemes llegats monolítics (Big Ball of Mud) contenen diversos models entremesclats. Definir Subdomains per a cada un d’aquests models lògics et permet tractar-los separadament, imaginar llenguatges ubiqüitaris propis i identificar quins són crítics per al teu projecte de Core Domain .
- **Aliniament de Bounded Context i Subdomain**
L’objectiu òptim és un **Bounded Context = 1 Subdomain**. Això manté cada context net i enfocat en el seu propi conjunt de conceptes estratègics. Si no és possible separar-los en contexts diferents, cal segregar el Supporting Subdomain dins del mateix context utilitzant un mòdul de codi independent domain-driven-design-di…domain-driven-design-di….
### Capítol 4 : Strategic Design with Context Mapping
El **Context Mapping** és una línia explícita entre dos **Bounded Contexts**, que captura la relació entre equips com un contracte tècnic d'integració entre ells.
Hi han diferents tipus de mapatge de contexte
- **Partnership**: Dos equips s'alineen en objectius compartits, sincronitzant-se sovint i aplicant integració continuada per mantenir els models en harmonia.
- **Shared Kernel**: Els equips comparteixen i mantenen conjuntament un subconjunt reduït del model comú, exigint coordinació estreta per evolucionar-lo amb seguretat.
- **Customer-Supplier**: Un equip (Supplier) proveeix un servei o model que un altre equip (Customer) consumeix; el Supplier controla què i quan s'entrega.
- **Conformist**: L'equip *downstream* adopta el model upstream "tal qual" perquè la traducció és massa costosa o complexe.
- **Anticorruption Layer**: L'equip downstream construeix una capa de traducció/adaptació per preservar la puresa del seu propi model i aïllar-se de conceptes aliens.
- **Open Host Service**: El Context upstream exposa una API ben documentada i senzilla d'utilitzar, facilitant la integració sense capes d'aïllament addicional.
- **Published Language**: Format de missatges compartit i basat en esquemes (JSON, Protobuf) en el qual diversos Contextx poden llegir i escriure amb confiança.
- **Separate ways**: Quan la integració aporta poc benefici, cada context implementa la seva pròpia solució i renuncia a compartir.
Per implementar-ho existeixen diferents tècniques d'integració:
- **RPC amb SOAP**: Estil trucada de procediment, però altament acoblada i fràgil davant fallades de xarxa.
- **RESTful HTTP**: Crides orientades a recursos; menys acoblament però requereix gestió d'errors i latència.
- **Messagins**: Cues asíncrones o pub/sub; molt robust però exigeix patrons de consistència eventual.
### Capítol 5 : Tactical Design with Aggregates
#### Perquè usar Aggregates
Els *Aggregates* són el patró tàctic clau per agrupar *Entities* i *Value objects*. Han de tenir consistència transaccional conjunta. Defineixen els límits clars de coherència i encapsulen la lògica de negoci relacionada.
#### Regles pràctiques per dissenyar Aggregates
1. **Protecció dels invariants de negoci dins dels límits de l'Aggregate**
1. Només l'Aggregate Root pot modificar l'estat intern, assegurant que cap regle de negoci es trenqui en cap operació.
2. **Dissenyar Aggregates petits**
1. Agrupar només les entitats estrictament necessàries per respectar els invariants, evitant clústers sobredimensionats que encareixin transaccions i compliquin la gestió de la memòria.
3. **Referencia altres Aggregates només per identitat**
1. Per desacoblar models, quan un Aggregate necessita veure o relacionar-se amb un altre, ha de guardar només la seva ID - no incorporar l'estat intern
4. **Actualitzar altres Aggregates amb eventual consistency**
1. Quan cal propagar canvis a *Aggregates* externs, s'usen *Domain Events* i mecanismes asíncrons, acceptant que la consistència esdevingui eventual més que immediata.
#### Modelant Aggregates
- **Elecció d'abstraccions** - tria noms i jerarquies d'entitats i *value objects* que reflecteixin clarament el concepte de negoci que volem modelar amb el llenguatge comú *Ubiquitous Language*.
- **Mida adequada** - Conjunt de regles per determinar la mida de cada *Aggregate*, de forma que no quedi massa anèmic (petit) ni massa gran (costós) **(TODO)**
- **Unitats testejables** - Cal definir l'**Aggregate** per tal que es puguin testejar de forma aïllada. Les operacions públiques han d'ésser validades per unit tests, tant dels *Aggregates* com *Entities* i *Value Objects* relacionats. Amb aquest testing hem d'assegurar el compliment de tots els invariants.
#### Parts d'un Aggregate
##### Aggregate
Un **Aggregate** és un conjunt d'objectes de domini que es tracten com una unitat de consistència transaccional.
Un **Aggregate** consta d'una o més **Entities** i, opcionalment, de **Value Objects**, on existeix sempre una *Entitat* específica que actua com a **AggregateRoot**.
Tots els objectes dins l'*Aggregate* s'han de trobar en un estat consistent quan es realitza la transacció que afecta a aquest; l'*Aggregate Root* controla i valida tots els canvis.
##### Entity
Una **Entitat** és un objecte de domini amb identitat única que pot canviar el seu estat al llarg del temps.
- Té **identitat pròpia**: disposa d'una clau o identificador que la distingeix de qualsevol altre entitat del mateix o un altre tipus. La defineix la seva individualitat, no només els seus atributs.
- **Mutabilitat**: normalment és mutable -el seu estat evoluciona- però podria ésser immutable si així convé.
- **Responsabilitat**: modelar conceptes de domini que necessiten ésser rastrejats de forma individual
##### Value Object
Un **Value Object** és una representació immutable d'un concepte que es defineix pels seus atributs.
- **No té identitat pròpia**: l'equivalència entre dos *Value objects* es determina comparant tots els seus valors interns, no per un identificador únic
- **Immutabilitat**: un cop creat, el seu estat no canvia; qualsevol "modificació" produeix un nou objecte.
- **Ús**: descriure, quantificar o mesurar característiques d'una *Entitat* o d'un *Aggregate* (per exemple, una adreça, un rang de dates, una quantitat monetària)
### Capítol 6: Tactical Design with Domain Events
#### Domain Event
És un registre d'un succés de negoci significatiu, expressat com un objecte amb un nom en passat ("ProductCreated", "InvoiceProcessed") i amb propietats que capturen el què i el quan de l'ocurrència. Cada esdeveniment sol implementar una interfície mínima amb una propietat `OccurredOn` per indicar la data i hora en què va tenir lloc.
#### Consistència causal
Garanteix que les operacions relacionades *causalment* es vegin en el mateix ordre per tots els nodes del sistema distribuït.
#### Modelatge i ús de Domain Events
1. **Disseny**: triar noms que reflecteixin la **Ubiquitous Language**, en passat i de forma explícita.
2. **Propietats**: incloure només les dades essencials per entendre l'esdeveniment
3. **Publicació**: després de guardar-los a l'*event store*, s'envien a tots els consumidors interessats, dins i fora del *Bounded Context*
#### Enriquiment vs Query-Back
+ **Enriquiment**: afegir en el propi esdeveniment totes les dades que potencialment necessitin els consumidors, maximitzant la seva autonomia.
+ **Query-Back**: mantenir l'esdeveniment lleuger i permetre als consumidors fer peticions *HTTP (REST/Open Host Service)* per obtenir la informació addicional quan sigui necessari.
#### Persistència i publicació conjunta
Cal guardar l'*Aggregate* i el seu *Domain Event* en la mateixa transacció (amb *Outbox/Inbox* o *Event Sourcing*)
#### Outbox/Inbox
##### Outbox
L’Outbox és una taula addicional dins de la mateixa base de dades on fas les operacions sobre l’Aggregate (o qualsevol entitat) que guarda, en la mateixa transacció, els Domain Events o missatges que has de publicar.
###### Com funciona?
1. **Transacció única**
- Quan el teu codi efectua un canvi de domini (p. ex., “ComandaConfirmada”), dins de la mateixa transacció SQL on actualitzes l’Aggregate afegeixes una fila a la taula `outbox` amb la càrrega del missatge (nom de l’esdeveniment, dades, timestamp, etc.)
2. **Desacoblament**
- Un procés extern (o un scheduler dins de l’aplicació) llegeix periòdicament les files noves de `outbox`, les envia al broker de missatges (Kafka, RabbitMQ, SNS, etc.) i —un cop confirmada la publicació— marca o elimina la fila de l’outbox.
3. **Garantia d’entrega**
- Com que l’insert a l’outbox i l’update de l’Aggregate són en una sola transacció, o bé ambdues passen o bé cap no passa; evites el risc de publicar un esdeveniment d’un canvi que no s’hagi aplicat.
---
##### Inbox
###### Què és?
L’Inbox és la contraparte per al consumidor de missatges. És una taula que manté el registre dels missatges entrants que ja has processat, per evitar duplicitats.
###### Com funciona?
1. **Recepció del missatge**
- Quan reps un esdeveniment des del broker, abans de fer cap operació de negoci comproves a la taula `inbox` si ja s’ha processat (buscant un identificador únic del missatge).
2. **Idempotència**
- Si no existeix, processàs la lògica de domini (per exemple, actualitzes un Aggregate) i, dins de la mateixa transacció, insertes un registre a `inbox` amb l’ID del missatge i el timestamp.
- Si ja existeix, simplement descartes el missatge sense repetir la lògica.
3. **Consistència**
- Això et permet tornar a rebre missatges (per reintents o fallades de xarxa) sense risc de processar-los doblement.
###### Beneficis
- **Atomicitat**: Outbox garanteix que l’actualització del domini i la publicació del missatge siguin atòmiques.
- **Resiliència**: si el broker o la xarxa falla, els missatges queden pendents a l’outbox fins que es puguin enviar.
- **Idempotència**: Inbox evita efectes duplicats al rebre missatges diverses vegades.
- **Desacoblament**: el productor i el consumidor no comparteixen transaccions, el que millora l’escalabilitat i tolerància a fallades.
En conjunt, l’Outbox/Inbox et permet implementar una **arquitectura basada en esdeveniments** amb **consistència eventual** de forma fiable i robusta, tot mantenint la integritat del teu model de domini
#### Event Sourcing
Tècnica que consisteix a emmagatzemar tots els *Domain Events* d'un *Aggregate* en un registre append-only (**Event Stream**). Reaplicant aquest flux d'esdeveniments es reconstitueix l'estat de l'Aggregate, cosa que permety
#### Snapshots i caching
Per a rendiment, convé mantenir **Aggregates** a memòria (Actor model) i emmagatzemar snapshots periòdics per evitar tornar a reproduir tots els events de l'inici cada vegada que s'ha de carregar l'Aggregate.
## Quotes
<!-- Notable quotes with reference to their page or location -->
## Bibliography
> `= this.bibliography`
---
## Tasks
<!-- What remains to be done with this note? -->
-
## References
<!-- Links to pages not referenced in the content -->
-
Event Storming
https://gamma.app/docs/Introduccio-a-lEventStorming-yy3aikly2re4pk6
Arquitectura Clean
https://gamma.app/docs/Arquitectura-Clean-Principis-i-Aplicacio-vdsxk5noqd4ybh6
DDD
https://gamma.app/docs/Domain-Driven-Design-Guia-Completa-0ips09is6oiw7o5