Cos'è il DDD (Domain-Driven Design)?

DDD (Domain-Driven Design) è un approccio alla progettazione software incentrato sul dominio aziendale. Scopri Bounded Context, aggregati, pattern tattici e strategici.

🔍

Cos'è il Domain-Driven Design (DDD)?

Il Domain-Driven Design (DDD), o Progettazione Guidata dal Dominio, è un approccio allo sviluppo software che pone il dominio aziendale al centro dell'architettura dell'applicazione. DDD promuove una stretta collaborazione tra esperti tecnici e di business per creare modelli software che riflettano accuratamente la realtà aziendale.

Il DDD è stato introdotto da Eric Evans nel suo libro fondamentale «Domain-Driven Design: Tackling Complexity in the Heart of Software» (Addison-Wesley, 2003). Da allora, è diventato uno degli approcci più influenti nella progettazione di sistemi enterprise complessi.

Secondo InfoQ (2023), il 65% delle organizzazioni che sono migrate a un'architettura a microservizi utilizzano i principi DDD per definire i confini dei servizi. Il ThoughtWorks Technology Radar classifica DDD nella categoria Adopt per progetti con elevata complessità di business logic.

📚

Concetti fondamentali

Ubiquitous Language (Linguaggio Ubiquo)

Il Linguaggio Ubiquo è il cuore del DDD: un vocabolario condiviso tra sviluppatori ed esperti di dominio, utilizzato in modo coerente nel codice, nella documentazione e nelle conversazioni.

Principi del Linguaggio Ubiquo:

  • Ogni termine è definito con precisione e concordato da tutti
  • Il linguaggio è riflesso direttamente nel codice sorgente
  • Ambiguità e sinonimi sono eliminati
  • Le modifiche al linguaggio si propagano a tutti gli artefatti

Esempio:

  • ❌ Ambiguo: «L'utente fa un'azione sul prodotto»
  • ✅ Ubiquo: «Il Cliente aggiunge un Articolo al Carrello»

Bounded Context (Contesto Delimitato)

Un Bounded Context è un confine esplicito all'interno del quale un modello di dominio specifico è valido e coerente. Ogni Bounded Context ha il proprio Linguaggio Ubiquo e il proprio modello.

Esempio: Sistema e-commerce

Bounded Context Significato di «Prodotto»
Catalogo Nome, descrizione, immagini, prezzo
Magazzino SKU, quantità, posizione
Spedizione Peso, dimensioni, imballaggio
Fatturazione Prezzo, IVA, codice fiscale

Context Map (Mappa dei Contesti)

La Mappa dei Contesti definisce le relazioni tra i diversi Bounded Context:

Pattern Descrizione
Shared Kernel Modello condiviso tra due contesti
Customer-Supplier Un contesto fornisce dati all'altro
Conformist Un contesto adotta completamente il modello dell'altro
Anti-Corruption Layer Layer protettivo per trasformare modelli
Open Host Service Interfaccia pubblica per più consumatori
Published Language Formato comune di scambio dati
🏗️

Pattern tattici del DDD

Entity (Entità)

Un'Entità è un oggetto definito dalla sua identità, non dai suoi attributi. Due entità con gli stessi attributi ma identità diverse sono oggetti distinti.

Esempi: Cliente, Ordine, Conto Bancario, Fattura

Caratteristiche:

  • Ha un identificatore univoco
  • È mutabile (può cambiare stato)
  • Ha un ciclo di vita
  • L'uguaglianza è basata sull'identità

Value Object (Oggetto Valore)

Un Value Object è un oggetto senza identità, definito esclusivamente dai suoi attributi. Due Value Object con gli stessi attributi sono considerati identici. Sono immutabili.

Esempi: Indirizzo, Importo (valuta + quantità), Coordinate GPS, Periodo date

Caratteristiche:

  • Nessun identificatore
  • Immutabile
  • Uguaglianza basata sugli attributi
  • Può essere sostituito, non modificato

Aggregate (Aggregato)

Un Aggregato è un cluster di entità e value object trattati come una singola unità per le operazioni di modifica dei dati. Ogni aggregato ha una Aggregate Root (radice) attraverso la quale avviene l'accesso esterno.

Regole di progettazione:

  1. Riferimenti all'aggregato solo attraverso la root
  2. Consistenza transazionale all'interno dell'aggregato
  3. Tra aggregati: eventual consistency
  4. Aggregati piccoli e focalizzati

Esempio: Aggregato Ordine

Ordine (Aggregate Root) ├── Riga Ordine (Entity) │ ├── Prodotto (Value Object) │ └── Quantità (Value Object) ├── Indirizzo Spedizione (Value Object) └── Totale (Value Object)

Domain Service (Servizio di Dominio)

Un Domain Service contiene logica di business che non appartiene naturalmente a nessuna entità o value object.

Esempi: Calcolo costo spedizione, verifica unicità email, trasferimento fondi

Domain Event (Evento di Dominio)

Un Domain Event è un fatto accaduto nel dominio di interesse per altre parti del sistema.

Esempi: «OrdineCreato», «PagamentoConfermato», «ArticoloSpedito»

Repository

Un Repository fornisce un'interfaccia per il recupero e la persistenza degli aggregati, astraendo i dettagli di storage.

Factory

Una Factory incapsula la logica complessa di creazione di oggetti di dominio, specialmente aggregati.

🔄

Progettazione strategica vs. tattica

Progettazione strategica

Focalizzata sull'architettura di alto livello:

  • Definizione dei Bounded Context
  • Costruzione della Context Map
  • Allineamento team-contesti
  • Scelta dei pattern di integrazione

Progettazione tattica

Focalizzata sui dettagli implementativi all'interno di un Bounded Context:

  • Progettazione di entità e value object
  • Definizione degli aggregati
  • Implementazione di repository e factory
  • Creazione di servizi ed eventi di dominio
🏛️

Architettura a strati del DDD

  1. Presentation Layer — UI e API
  2. Application Layerorchestrazione use case
  3. Domain Layer — business logic (il cuore)
  4. Infrastructure Layer — database, messaging, API esterne

Le dipendenze puntano verso l'interno: gli strati esterni dipendono da quelli interni, mai il contrario.

📊

DDD e Microservizi

DDD e microservizi sono alleati naturali:

  • Bounded Context ≈ Microservizio
  • Il Linguaggio Ubiquo definisce i contratti API
  • I Domain Event abilitano l'architettura event-driven
  • Gli Aggregati definiscono i confini transazionali

Event Storming

Event Storming, creato da Alberto Brandolini, è un metodo collaborativo di modellazione:

  • 🟧 Domain Event — cosa è successo?
  • 🟦 Command — cosa ha causato l'evento?
  • 🟨 Aggregate — chi processa il comando?
  • 🟪 Policy — quali reazioni all'evento?
  • 🟩 Read Model — quali informazioni servono?
📈

Statistiche e fatti

  • Il 78% delle aziende fintech usa DDD per il core system (Gartner, 2023)
  • Il 65% delle organizzazioni con microservizi applica i Bounded Context (InfoQ, 2023)
  • I progetti con DDD mostrano un 40% di riduzione dei difetti nella business logic (IEEE Software, 2022)
  • Una sessione di Event Storming (2–3 giorni) sostituisce 2–4 settimane di analisi tradizionale

Domande frequenti (FAQ)

Quando conviene usare DDD?

DDD è più efficace per progetti con business logic complessa. Per semplici CRUD, DDD potrebbe essere eccessivo.

DDD è solo per microservizi?

No. DDD può essere applicato anche in sistemi monolitici. I Bounded Context possono essere moduli all'interno di un monolito.

Qual è la differenza tra DDD e CRUD?

CRUD è orientato ai dati (create, read, update, delete). DDD è orientato al comportamento di business. In DDD, il modello riflette i processi aziendali, non la struttura del database.

Come iniziare con DDD?

  1. Conducete un Event Storming con gli esperti di dominio
  2. Identificate i Bounded Context e il Linguaggio Ubiquo
  3. Costruite la Context Map
  4. Iniziate la progettazione tattica dal contesto più critico
  5. Iterate e raffinate il modello in ogni sprint

Cos'è l'Anti-Corruption Layer?

L'Anti-Corruption Layer (ACL) è uno strato protettivo che traduce il modello di un sistema esterno nel modello del vostro dominio, prevenendo la «contaminazione» della vostra domain model.

🔗
🍄

Vuoi saperne di più?

Se vuoi saperne di più riguardo a DDD — Domain-Driven Design, contattami su X. Amo condividere idee, rispondere alle domande e discutere curiosità su questi argomenti, quindi non esitare a fare un salto. A presto!