Uso di DDD tattico per progettare microservizi

Azure Migrate

La progettazione basata su dominio (DDD) si oppone all'idea di avere un unico modello unificato per l'intero sistema; incoraggia invece la divisione del sistema in contesti delimitati, ognuno dei quali ha un proprio modello. Durante la fase strategica della progettazione basata su domini, si esegue il mapping del dominio aziendale e si definiscono i contesti delimitati per i modelli di dominio.

La progettazione basata su domini tattica consente di definire i modelli di dominio con maggiore precisione. Gli schemi tattici vengono applicati all'interno di un singolo contesto delimitato. In un'architettura di microservizi, in cui ogni contesto delimitato è un candidato di microservizio, è particolarmente interessato ai modelli di entità e aggregazione. L'applicazione di questi modelli consentirà di identificare i limiti naturali per i servizi nell'applicazione (vedere l'articolo successivo in questa serie). In linea generale, un microservizio non deve essere più piccolo di un'aggregazione e non deve essere più grande di un contesto delimitato. Verranno innanzitutto esaminati gli schemi tattici e quindi verranno applicati al contesto delimitato per il recapito nell'applicazione di recapito tramite drone.

Panoramica degli schemi tattici

Questa sezione fornisce un breve riepilogo degli schemi di progettazione basata su dominio tattica. Se si ha già familiarità con questo tipo di progettazione, è possibile ignorare questa sezione. I modelli sono descritti in modo più dettagliato nei capitoli da 5 a 6 del libro di Eric Evans e nell'implementazione del design basato su dominio di Vaughn Vernon.

Diagramma degli schemi tattici nella progettazione basata su dominio

Entità. Un'entità è un oggetto con un'identità univoca che persiste nel tempo. Ad esempio, in un'applicazione bancaria i clienti e i conti sono entità.

  • Un'entità presenta un identificatore univoco nel sistema che può essere usato per cercare o recuperare l'entità. Questo non significa che l'identificatore sia sempre esposto direttamente agli utenti. Può essere un GUID o una chiave primaria in un database.
  • Un'identità può estendersi su più contesti delimitati e può persistere oltre la durata dell'applicazione. Ad esempio, i numeri dei conti bancari o i documenti di identità rilasciati dal governo non sono legati alla durata di un'applicazione specifica.
  • Gli attributi di un'entità possono cambiare nel tempo. Ad esempio, il nome o l'indirizzo di una persona possono cambiare, ma si tratta comunque dello stesso individuo.
  • Un'entità può contenere riferimenti ad altre entità.

Oggetti valore. Un oggetto valore non ha identità. È definito esclusivamente dai valori dei relativi attributi. Gli oggetti valore non sono modificabili. Per aggiornare un oggetto valore, è sempre necessario creare una nuova istanza per sostituire quella precedente. Gli oggetti valore possono includere metodi che incapsulano la logica del dominio, ma tali metodi non devono avere effetti collaterali sullo stato dell'oggetto. Alcuni esempi tipici di oggetti valore sono i colori, le date e ore e i valori di valuta.

Aggregazioni. Un'aggregazione definisce un limite di coerenza per una o più entità. In un'aggregazione solo un'entità costituisce la radice. La ricerca viene eseguita tramite l'identificatore dell'entità radice. Le altre entità nell'aggregazione sono elementi figlio della radice e vi fanno riferimento i puntatori seguenti dalla radice.

Lo scopo di un'aggregazione è la modellazione di invarianti transazionali. Gli elementi nel mondo reale hanno reti di relazioni complesse. I clienti creano gli ordini, gli ordini contengono prodotti, i prodotti hanno fornitori e così via. Se l'applicazione modifica diversi oggetti correlati, come può garantire la coerenza? Come si tiene traccia delle invarianti e come vengono imposte?

Le applicazioni tradizionali spesso usano le transazioni di database per imporre la coerenza. In un'applicazione distribuita, tuttavia, spesso non è fattibile. Una singola transazione aziendale può interessare più archivi dati, può essere caratterizzata da un'esecuzione prolungata o può coinvolgere servizi di terze parti. È compito dell'applicazione e non del livello dati imporre le invarianti necessarie per il dominio. Ecco che cosa modellano le aggregazioni.

Nota

Un'aggregazione può essere costituita da una singola entità, senza entità figlio. Ciò che la rende un'aggregazione sono i limiti transazionali.

Servizi di dominio e servizi dell'applicazione. Nella terminologia della progettazione basata su domini un servizio è un oggetto che implementa una logica senza bloccare uno stato. Evans distingue tra servizi di dominio che incapsulano la logica del dominio e servizi dell'applicazione che forniscono funzionalità tecniche, ad esempio l'autenticazione degli utenti o l'invio di messaggi SMS. I servizi di dominio vengono spesso usati per modellare il comportamento che si estende su più entità.

Nota

Nel settore dello sviluppo software, il termine servizio ha molti significati. La definizione fornita qui non è direttamente correlata ai microservizi.

Eventi del dominio. Gli eventi del dominio consentono di comunicare ad altre parti del sistema quando si verifica un evento. Come suggerito dal nome, gli eventi di dominio indicano qualcosa che accade all'interno del dominio. Ad esempio "un record è stato inserito in una tabella" non è un evento di dominio. "Un recapito è stato annullato" è invece un evento del dominio. Gli eventi di dominio sono particolarmente importanti in un'architettura di microservizi. Poiché i microservizi sono distribuiti e non condividono archivi dati, gli eventi di dominio consentono ai microservizi di coordinarsi tra loro. L'articolo Comunicazioni tra servizi illustra in modo più dettagliato la messaggistica asincrona.

Esistono alcuni altri schemi di progettazione basata su dominio non elencati in questo documento, ad esempio factory, repository e moduli. Questi schemi possono risultare utili per implementare un microservizio ma sono meno pertinenti nella fase di progettazione dei limiti tra microservizi.

Recapito tramite drone: applicazione degli schemi

Si inizia con gli scenari che dovrà gestire il contesto delimitato per il recapito.

  • Un cliente può richiedere che un drone ritiri la merce da un'azienda registrata presso il servizio di recapito tramite drone.
  • Il mittente genera un'etichetta (codice a barre o RFID) da posizionare sul pacchetto.
  • Un drone ritirerà e consegnerà il pacchetto dall'indirizzo di origine all'indirizzo di destinazione.
  • Quando un cliente pianifica un recapito, il sistema fornisce un tempo stimato di completamento in base alle informazioni sull'itinerario, alle condizioni meteo e ai dati storici.
  • Quando il drone è in volo, un utente può monitorare la posizione corrente e il tempo stimato per il completamento più recente.
  • Fintanto che un drone non ritira il pacchetto, il cliente può ancora annullare il recapito.
  • Il cliente riceve una notifica relativa all'avvenuto recapito.
  • Il mittente può richiedere la conferma di recapito dal cliente, sotto forma di firma o impronta digitale.
  • Gli utenti possono visualizzare la cronologia di un recapito completato.

Da questi scenari, il team di sviluppo ha identificato le entità seguenti.

  • Consegna
  • Pacchetto
  • Drone
  • Conto
  • Conferma
  • Notifica
  • Tag

Le prime quattro, ovvero recapito, pacchetto, drone e account, sono tutte aggregazioni che rappresentano limiti di coerenza transazionali. Le conferme e le notifiche sono entità figlio delle consegne e le etichette sono entità figlio dei pacchetti.

Gli oggetti valore in questa progettazione includono l'indirizzo, il tempo stimato per il completamento, il peso del pacchetto e le dimensioni del pacchetto.

A titolo di esempio, ecco un diagramma UML dell'aggregazione relativa al recapito. Si noti che include riferimenti ad altre aggregazioni, ovvero account, pacchetto e drone.

Diagramma UML dell'aggregazione relativa al recapito

Sono presenti due eventi di dominio:

  • Mentre un drone è in volo, l'entità drone invia eventi DroneStatus che descrivono la posizione e lo stato (in volo, atterrato) del drone.

  • L'entità recapito invia eventi DeliveryTracking ogni volta che cambia la fase di una consegna. I valori sono DeliveryCreated, DeliveryRescheduled, DeliveryHeadedToDropoff e DeliveryCompleted.

Si noti che questi eventi descrivono elementi che risultano significativi all'interno del modello di dominio. Forniscono informazioni sul dominio e non sono legati a un costrutto di linguaggio di programmazione specifico.

Il team di sviluppo ha identificato un'altra area di funzionalità, che non rientra perfettamente nelle entità descritte finora. Alcune parti del sistema devono coordinare tutte le fasi coinvolte nella pianificazione o nell'aggiornamento di una consegna. Pertanto, il team di sviluppo ha aggiunto due servizi di dominio alla progettazione: un'utilità di pianificazione che coordina i passaggi e un supervisore che monitora lo stato di ogni passaggio, per rilevare se i passaggi hanno avuto esito negativo o timeout. Si tratta di una variante del modello Supervisore agente di pianificazione.

Diagramma del modello di dominio modificato

Passaggi successivi

Il passaggio successivo consiste nel definire i limiti per ogni microservizio.