Il Domain Driven Design applicato ai dati per una maggiore agilità nella progettazione

Giulio Scotti
Quantyca
Published in
8 min readJun 8, 2022
Photo by Sigmund on Unsplash

Abstract

Questo è il quinto articolo di una serie di blog post finalizzata a trasmettere i punti salienti della visione delle architetture IT enterprise e del Data Management che, come Quantyca, proponiamo ai nostri clienti.

Per chi non li avesse letti, consiglio di leggere gli articoli precedenti della serie, dai titoli:

Negli articoli successivi tratteremo ulteriori aspetti che riteniamo interessanti per costruire piattaforme dati in grado di rispondere alle esigenze pressanti di un business che sta diventando sempre più data-driven.

Questo l’elenco dei prossimi articoli:

Il Domain Driven Design e la decentralizzazione delle responsabilità

Nel ventennio scorso, nell’ambito dello sviluppo software, si è affermato un modello di progettazione software chiamato Domain Driven Design (DDD), proposto inizialmente da Eric Evans nel 2003 e esteso successivamente da Vaughn Vernon; in particolare, l’approccio ha visto una nuova ondata di diffusione negli ultimi anni con l’adozione sempre più marcata dello stile architetturale a microservizi. Il modello DDD propone alcuni strumenti di progettazione strategica e altri di progettazione tattica: in questo articolo discuteremo solo il sottoinsieme dei concetti di interesse per le implicazioni sui processi di Data Management.

Il Domain Driven Design si fonda sull’idea che un dominio applicativo complesso difficilmente può essere implementato da un unico modello software, in quanto uno stesso concetto di business può assumere significati e proprietà differenti in base al particolare contesto in cui viene utilizzato.

Per chiarire il concetto, facciamo l’esempio della Transazione di Vendita per un’azienda che opera nel settore della grande distribuzione. La prospettiva di interesse e, di conseguenza, le proprietà rilevanti dell’entità Transazione di Vendita nell’ambito delle analisi commerciali e della valutazione dei fornitori possono essere abbastanza differenti dal significato con cui si usa il medesimo termine nel contesto della segmentazione clienti e dei processi di loyalty, piuttosto che della gestione della logistica dei magazzini o, ancora, dei processi finanziari e contabili.

Nell’esempio illustrato, sarebbe arduo rappresentare le diverse accezioni del concetto di Transazione di Vendita in un’unica classe o gerarchia di classi (ipotizzando che si scelga un paradigma di programmazione ad oggetti): uno sforzo in tale direzione produrrebbe un’entità dal significato sfumato e ambiguo, che non soddisferebbe le esigenze specifiche dei vari contesti di dominio e rischierebbe di dar vita ad un modello software complesso, ad alto accoppiamento e senza nessun confine logico tra le sue sottoparti.

Progettazione del software che non segue il modello Domain Driven Design.

Un modello simile ha spesso conseguenze negative sulla manutenibilità e sull’agilità di evoluzione dell’applicazione: diversi team presumibilmente andrebbero a lavorare sullo stesso progetto software, gli impatti di una modifica creerebbero, con buona probabilità, effetti a cascata su diverse parti del modello di difficile governo. Questi comporterebbero interdipendenze e necessità di coordinamento tra team di lavoro che avrebbero l’effetto di rallentare la delivery delle funzionalità richieste dal business e aumentare i costi del progetto.

Il Domain Driven Design propone di andare in direzione opposta: il dominio applicativo complessivo viene scomposto in diversi Bounded Context, il cui confine logico è definito in modo esplicito, all’interno di ciascuno dei quali il significato di un’entità del modello è inequivocabile e univoco, specifico del particolare contesto. L’insieme dei termini per cui vale un determinato significato semantico all’interno di un Bounded Context è detto Ubiquitous Language, in quanto è business-oriented e si permea sia nel linguaggio comune del team che gestisce il Bounded Context, sia nel codice applicativo, nel modello concettuale, logico e fisico del software e dei dati alla base, nel nome degli eventi, delle API e in tutti gli aspetti implementativi.

Tornando all’esempio considerato in precedenza, in ciascun Bounded Context di interesse verrà definita un’entità Transazione di Vendita, indipendente e disaccoppiata dalla medesima entità negli altri Bounded Context: nel contesto dei processi commerciali verranno potenzialmente rappresentati gli attributi della transazione di rilievo per analizzare e gestire i fornitori, nel contesto della gestione loyalty e segmentazione clienti si modelleranno gli attributi che permettono di ricollegare la transazione ad uno specifico cliente e al suo comportamento di acquisto. Nel contesto della logistica saranno invece definiti gli attributi necessari per gestire l’inventario, i rifornimenti, i movimenti di merce; infine, nel contesto finanziario / contabile si porrà il focus sugli attributi relativi ai fattori di cambio, alla percentuale di tassazione, al valore a costo dei prodotti venduti.

Progettazione software che scompone lo spazio soluzione in Bounded Context, secondo i principi del Domain Driven Design

In ciascun contesto il significato semantico del linguaggio è protetto dalle perturbazioni esterne e, ogni qual volta è necessaria un’interazione (e di conseguenza uno scambio di informazioni) tra diversi Bounded Context, deve essere prevista una trasformazione di contesto, detta Context Mapping, per permettere di adattare il significato delle entità condivise proprio del contesto sorgente nel linguaggio adatto per l’utilizzo da parte del contesto ricevente. Esistono diverse forme di Context Mapping, da quelle a più alto accoppiamento, ad esempio il mapping di tipo Shared Kernel, in cui due Bounded Context condividono un sottoinsieme del modello software e si coordinano per evolverlo, a quelle a più basso accoppiamento. Un esempio comune è il mapping che prevede un Anti Corruption Layer: all’ingresso del Bounded Context ricevente viene sviluppato un livello software per tradurre il linguaggio straniero e potenzialmente contaminante del Bounded Context sorgente nel modello software autentico e puro del contesto ricevente: questo è particolarmente utile negli scenari in cui il contesto sorgente è un sistema legacy con un modello Big Ball Of Mud e il contesto ricevente è un microservizio moderno.

Il Domain Driven Design si basa pertanto su una strategia Divide Et Impera, per permettere di scomporre lo spazio problema (il dominio) in componenti più piccole (dette Sottodomini): la soluzione verrà implementata per mezzo di diversi Bounded Context, ciascuno dei quali possiede un perimetro semantico e un linguaggio caratterizzante e unico, l’Ubiquitous Language.

I vantaggi di un simile approccio sono molteplici: in primo luogo è possibile assegnare un singolo Bounded Context ad un team specifico e i diversi team hanno la possibilità di evolvere e controllare il software e il modello dati del Bounded Context in modo autonomo, secondo il proprio passo di delivery, minimizzando l’interdipendenza con altri team e la necessità di coordinamento; in secondo luogo, la complessità di dominio dei singoli Bounded Context rimane entro limiti gestibili, evitando di creare software troppo estesi e con dipendenze intrinseche che ne rendono difficile l’evoluzione. Infine, il significato degli elementi del modello e dei concetti semantici dentro il perimetro del Bounded Context rimane puro, autentico e specifico del contesto, evitando di creare ambiguità o eccessive generalizzazioni finalizzate a rappresentare sfaccettature diverse, che spesso sono causa di inconsistenze.

Sotto l’aspetto delle integrazioni di dati e servizi, il Domain Driven Design ha delle implicazioni rilevanti: infatti, mentre all’interno del perimetro di un Bounded Context è ammissibile che le applicazioni (ad esempio i microservizi) comunichino in modo diretto, tramite chiamate API sincrone o condivisione di database, in quanto le applicazioni ricadono sotto la ownership di un unico team, è fortemente raccomandato che le integrazioni tra Bounded Context differenti siano il più possibile a basso accoppiamento, comunicando tramite interfacce stabili e che astraggano la complessità i dettagli implementativi privati del Bounded Context. Solitamente, per la comunicazione inter Bounded Context si usa lo stile event-driven, basato su pubblicazione e sottoscrizione di comandi ed eventi di dominio tramite broker di messaggi (data bus).

Integrazione tra diversi Bounded Context, basata sulla condivisione di eventi di dominio tramite una piattaforma di messaging.

Con l’affermazione dello stile architetturale a microservizi per lo sviluppo di applicazioni moderne e scalabili, è diventato possibile applicare in modo più efficace il Domain Driven Design rispetto che in precedenza: l’intero progetto software è implementato da diverse unità di deploy, i microservizi, detti architectural quanta, ciascuno dei quali afferisce ad un determinato Bounded Context ed è gestito in modo autonomo dal team owner del Bounded Context. Accettando di scomporre un’unica applicazione logica in diverse unità di deploy fisiche si rende ancora più forte l’indipendenza dei Bounded Context, in quanto questa si concretizza in una scelta indipendente degli stack tecnologici con cui implementare i servizi e in una segregazione fisica degli ambienti, della base di codice e degli strumenti di lavoro.

L’orientamento Domain Driven Design non solo ha prodotto risultati immediati nel mondo dello sviluppo software, ma ha anche generato un’influenza significativa negli studi innovativi sulle tecniche di Data Management: si è iniziato a comprendere che la decentralizzazione delle responsabilità sui dati e l’organizzazione domain-oriented potesse dare benefici anche nella gestione di tutte le fasi del ciclo di vita del dato, dall’offloading dalle sorgenti, passando per le fasi di integrazione e trasformazione, fino all’utilizzo da parte delle applicazioni analitiche. Il risultato è stata la proposta di un nuovo paradigma per la gestione dei dati, chiamato Data Mesh, che discuteremo nei prossimi articoli.

--

--