Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Suggerimento
Questo contenuto è un estratto dell'eBook, Architettura di microservizi .NET per applicazioni .NET containerizzati, disponibile in documentazione .NET o come PDF scaricabile gratuitamente leggibile offline.
Definire un modello di dominio avanzato per ogni microservizio aziendale o contesto delimitato.
L'obiettivo è creare un singolo modello di dominio coesivo per ogni microservizio aziendale o contesto delimitato (BC). Tenere presente, tuttavia, che a volte un microservizio bc o aziendale può essere costituito da diversi servizi fisici che condividono un singolo modello di dominio. Il modello di dominio deve acquisire le regole, il comportamento, il linguaggio aziendale e i vincoli del singolo Contesto Delimitato o microservizio aziendale che rappresenta.
Modello di entità di dominio
Le entità rappresentano gli oggetti di dominio e sono definite principalmente dall'identità, dalla continuità e dalla persistenza nel tempo e non solo dagli attributi che li compongono. Come dice Eric Evans, "un oggetto definito principalmente dalla sua identità è chiamato un'entità". Le entità sono molto importanti nel modello di dominio, poiché sono la base per un modello. Pertanto, è necessario identificarli e progettarli con attenzione.
L'identità di un'entità può attraversare più microservizi o contesti delimitati.
La stessa identità (vale a dire lo stesso Id
valore, anche se forse non la stessa entità di dominio) può essere modellata in più contesti delimitati o microservizi. Ciò non implica tuttavia che la stessa entità, con gli stessi attributi e la stessa logica vengano implementati in più contesti delimitati. Le entità in ogni contesto delimitato limitano invece gli attributi e i comportamenti a quelli necessari nel dominio del contesto delimitato.
Ad esempio, l'entità acquirente potrebbe avere la maggior parte degli attributi di una persona definiti nell'entità utente nel microservizio profilo o identità, inclusa l'identità. Tuttavia, l'entità acquirente nel microservizio di ordinamento potrebbe avere meno attributi, perché solo determinati dati acquirenti sono correlati al processo di ordine. Il contesto di ogni microservizio o contesto delimitato influisce sul modello di dominio.
Le entità di dominio devono implementare il comportamento oltre all'implementazione degli attributi dei dati.
Un'entità di dominio in DDD deve implementare la logica o il comportamento del dominio correlati ai dati dell'entità (l'oggetto a cui si accede in memoria). Ad esempio, come parte di una classe di entità ordine, è necessario che la logica di business e le operazioni siano implementate come metodi per attività quali l'aggiunta di un elemento dell'ordine, la convalida dei dati e il calcolo del totale. I metodi dell'entità si occupano delle invarianti e delle regole dell'entità anziché di quelle distribuite nel livello dell'applicazione.
La figura 7-8 mostra un'entità di dominio che implementa non solo attributi di dati, ma operazioni o metodi con logica di dominio correlata.
Figura 7-8. Esempio di progettazione di un'entità di dominio che implementa i dati più il comportamento
Un'entità modello di dominio implementa i comportamenti tramite metodi, ovvero non è un modello "anemico". Naturalmente, a volte è possibile avere entità che non implementano alcuna logica come parte della classe di entità. Ciò può verificarsi nelle entità figlio all'interno di un'aggregazione se l'entità figlio non dispone di alcuna logica speciale perché la maggior parte della logica è definita nella radice di aggregazione. Se si dispone di un microservizio complesso con logica implementata nelle classi di servizio anziché nelle entità di dominio, è possibile che si verifichi un calo nel modello di dominio anemico, come illustrato nella sezione seguente.
Modello di dominio avanzato e modello di dominio anemico
Nel suo post AnemicDomainModel, Martin Fowler descrive un modello di dominio anemico in questo modo:
Il sintomo di base di un modello di dominio anemico è che al primo sguardo sembra la cosa reale. Ci sono oggetti, molti denominati dopo i sostantivi nello spazio di dominio, e questi oggetti sono connessi con le relazioni avanzate e la struttura che i modelli di dominio reali hanno. La difficoltà emerge quando si osserva il comportamento, e ci si rende conto che non c'è quasi alcun comportamento su questi oggetti, rendendoli poco più che semplici contenitori di getter e setter.
Naturalmente, quando si usa un modello di dominio anemico, questi modelli di dati verranno usati da un set di oggetti servizio (tradizionalmente denominato livello business) che acquisisce tutto il dominio o la logica di business. Il livello business si trova sopra il modello di dati e utilizza il modello di dati proprio come dati.
Il modello di dominio anemico è solo una progettazione di stile procedurale. Gli oggetti entità anemici non sono oggetti reali perché mancano di comportamento (metodi). Contengono solo proprietà dei dati e quindi non sono orientate agli oggetti. Inserendo tutto il comportamento negli oggetti di servizio (il livello commerciale), si finisce essenzialmente con codice spaghetti o script di transazioni e quindi si perdono i vantaggi offerti da un modello di dominio.
Indipendentemente dal fatto che il microservizio o il contesto delimitato sia molto semplice (un servizio CRUD), il modello di dominio anemico sotto forma di oggetti entità con solo proprietà di dati potrebbe essere sufficiente e potrebbe non essere utile implementare modelli DDD più complessi. In tal caso, sarà semplicemente un modello di persistenza, perché è stata creata intenzionalmente un'entità con solo i dati a scopo CRUD.
Ecco perché le architetture di microservizi sono perfette per un approccio multi-architetturale a seconda di ogni contesto delimitato. Ad esempio, in eShopOnContainers, il microservizio di ordinamento implementa modelli DDD, ma il microservizio catalogo, che è un semplice servizio CRUD, non lo è.
Alcune persone dicono che il modello di dominio anemico è un anti-modello. Dipende davvero da ciò che si sta implementando. Se il microservizio che si sta creando è abbastanza semplice (ad esempio, un servizio CRUD), seguendo il modello di dominio anemico non è un antimodello. Tuttavia, se è necessario affrontare la complessità del dominio di un microservizio con numerose regole business in continua evoluzione, il modello di dominio anemico potrebbe essere un anti-modello per tale microservizio o contesto delimitato. In tal caso, la progettazione come modello avanzato con entità contenenti dati e comportamento, nonché l'implementazione di modelli DDD aggiuntivi (aggregazioni, oggetti valore e così via) potrebbero avere enormi vantaggi per il successo a lungo termine di tale microservizio.
Risorse aggiuntive
DevIQ. Entità del dominio
https://deviq.com/entity/Martin Fowler. Modello di dominio
https://martinfowler.com/eaaCatalog/domainModel.htmlMartin Fowler. Modello di dominio Anemic
https://martinfowler.com/bliki/AnemicDomainModel.html
Modello oggetto Value
Come ha notato Eric Evans, "Molti oggetti non hanno un'identità concettuale. Questi oggetti descrivono alcune caratteristiche di una cosa."
Un'entità richiede un'identità, ma esistono molti oggetti in un sistema che non lo fanno, ad esempio il modello Value Object. Un oggetto valore è un oggetto senza identità concettuale che descrive un aspetto del dominio. Si tratta di oggetti di cui si crea un'istanza per rappresentare elementi di progettazione che interessano solo temporaneamente. Ti interessa quello che sono, non chi sono. Gli esempi includono numeri e stringhe, ma possono anche essere concetti di livello superiore, ad esempio gruppi di attributi.
Un'entità di un microservizio potrebbe non essere un'entità in un altro microservizio, perché nel secondo caso il contesto delimitato potrebbe avere un significato diverso. Ad esempio, un indirizzo in un'applicazione di e-commerce potrebbe non avere un'identità, poiché potrebbe rappresentare solo un gruppo di attributi del profilo del cliente per una persona o una società. In questo caso, l'indirizzo deve essere classificato come oggetto valore. Tuttavia, in un'applicazione per una società di utilità elettrica, l'indirizzo del cliente potrebbe essere importante per il dominio aziendale. Pertanto, l'indirizzo deve avere un'identità in modo che il sistema di fatturazione possa essere collegato direttamente all'indirizzo. In tal caso, un indirizzo deve essere classificato come entità di dominio.
Una persona con un nome e un cognome è in genere un'entità perché una persona ha un'identità, anche se il nome e il cognome coincidono con un altro set di valori, ad esempio se tali nomi fanno riferimento a una persona diversa.
Gli oggetti valore sono difficili da gestire in database relazionali e ORM come Entity Framework (EF), mentre nei database orientati ai documenti sono più facili da implementare e usare.
EF Core 2.0 e versioni successive includono la funzionalità Entità di proprietà che semplifica la gestione degli oggetti valore, come vedremo più avanti in dettaglio.
Risorse aggiuntive
Martin Fowler. Modello oggetto valore
https://martinfowler.com/bliki/ValueObject.htmlOggetto di Valore
https://deviq.com/value-object/Oggetti Value nello sviluppo di Test-Driven
https://leanpub.com/tdd-ebook/read#leanpub-auto-value-objectsEric Evans. Domain-Driven design: affrontare la complessità nel cuore del software. (Libro; include una discussione sugli oggetti di valore)
https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/
Modello di aggregazione
Un modello di dominio contiene cluster di entità e processi di dati diversi che possono controllare un'area significativa di funzionalità, ad esempio l'evasione degli ordini o l'inventario. Un'unità DDD con granularità più fine è l'aggregazione, che descrive un cluster o un gruppo di entità e comportamenti che possono essere considerati un'unità coesa.
In genere si definisce un'aggregazione basata sulle transazioni necessarie. Un esempio classico è un ordine che contiene anche un elenco di elementi degli ordini. Un elemento dell'ordine sarà in genere un'entità. Ma sarà un'entità figlia all'interno dell'aggregato dell'ordine, che conterrà anche l'entità ordine come entità radice, generalmente chiamata radice di aggregazione.
L'identificazione delle aggregazioni può essere difficile. Un'aggregazione è un gruppo di oggetti che devono essere coerenti tra loro, ma non è sufficiente selezionare un gruppo di oggetti ed etichettarli come aggregazione. È necessario iniziare con un concetto di dominio e considerare le entità usate nelle transazioni più comuni correlate a tale concetto. Le entità che devono essere coerenti in modo transazionale sono quelle che costituiscono un'aggregazione. Pensare alle operazioni di transazione è probabilmente il modo migliore per identificare le aggregazioni.
Modello di radice dell'aggregato o Entità radice
Un'aggregazione è costituita da almeno un'entità: la radice di aggregazione, detta anche entità radice o entità primaria. Inoltre, può avere più entità figlie e oggetti di valore, in cui tutte le entità e gli oggetti lavorano insieme per implementare il comportamento e le transazioni necessari.
Lo scopo di una radice di aggregazione è garantire la coerenza dell'aggregazione; deve essere l'unico punto di ingresso per gli aggiornamenti all'aggregazione tramite metodi o operazioni nella classe radice di aggregazione. È necessario apportare modifiche alle entità all'interno dell'aggregazione solo tramite la radice di aggregazione. Si tratta del guardiano della coerenza dell'aggregazione, considerando tutte le invarianti e le regole di coerenza che potrebbe essere necessario rispettare nell'aggregazione. Se si modifica un'entità figlio o un oggetto valore in modo indipendente, la radice di aggregazione non può garantire che l'aggregazione sia in uno stato valido. Sarebbe come un tavolo con una gamba sciolta. Mantenere la coerenza è lo scopo principale della radice di aggregazione.
Nella figura 7-9 è possibile visualizzare aggregazioni di esempio come l'aggregazione acquirente, che contiene una singola entità (l'acquirente radice aggregato). L'aggregazione dell'ordine contiene più entità e un oggetto valore.
Figura 7-9. Esempio di aggregazioni con più o singole entità
Un modello di dominio DDD è costituito da aggregazioni, un'aggregazione può avere solo un'entità o più e può includere anche oggetti valore. Si noti che l'aggregato Buyer potrebbe avere entità figlio aggiuntive, a seconda del vostro dominio, come avviene nel microservizio di ordinamento nell'applicazione di riferimento eShopOnContainers. La figura 7-9 illustra solo un caso in cui l'acquirente ha una singola entità, come esempio di un'aggregazione che contiene solo una radice di aggregazione.
Per mantenere la separazione delle aggregazioni e mantenere chiari i limiti tra di essi, è consigliabile in un modello di dominio DDD impedire lo spostamento diretto tra aggregazioni e avere solo il campo chiave esterna (FK), come implementato nel modello di dominio del microservizio ordering in eShopOnContainers. L'entità Order ha solo un campo chiave esterna per l'acquirente, ma non una proprietà di navigazione di EF Core, come illustrato nel codice seguente:
public class Order : Entity, IAggregateRoot
{
private DateTime _orderDate;
public Address Address { get; private set; }
private int? _buyerId; // FK pointing to a different aggregate root
public OrderStatus OrderStatus { get; private set; }
private readonly List<OrderItem> _orderItems;
public IReadOnlyCollection<OrderItem> OrderItems => _orderItems;
// ... Additional code
}
L'identificazione e l'uso delle aggregazioni richiedono ricerca ed esperienza. Per altre informazioni, vedere l'elenco di risorse aggiuntive seguente.
Risorse aggiuntive
Vaughn Vernon. Progettazione efficace dell'aggregazione - Parte I: Modellazione di una singola aggregazione (da https://dddcommunity.org/)
https://dddcommunity.org/wp-content/uploads/files/pdf_articles/Vernon_2011_1.pdfVaughn Vernon. Progettazione efficace degli aggregati - Parte II: Far lavorare gli aggregati insieme (da https://dddcommunity.org/)
https://dddcommunity.org/wp-content/uploads/files/pdf_articles/Vernon_2011_2.pdfVaughn Vernon. Progettazione efficace degli aggregati - Parte III: Approfondimento delle conoscenze attraverso la scoperta (da https://dddcommunity.org/)
https://dddcommunity.org/wp-content/uploads/files/pdf_articles/Vernon_2011_3.pdfSergey Grybniak. Modelli di progettazione tattica DDD
https://www.codeproject.com/Articles/1164363/Domain-Driven-Design-Tactical-Design-Patterns-PartChris Richardson. Sviluppo di microservizi transazionali tramite aggregazioni
https://www.infoq.com/articles/microservices-aggregates-events-cqrs-part-1-richardsonDevIQ. Modello di aggregazione
https://deviq.com/aggregate-pattern/