La lettura del Blue Book può generare reazioni che vanno dal "Cargo cult" (a.k.a. "non avrai altro Modello all’infuori di me") a "’sta roba non mi serve: io faccio gestionali, non applicazioni che lanciano i razzi sulla Luna".
Previa una attualizzazione dei concetti del Blue Book, che ha ormai compiuto 10 anni, in questa sessione affronteremo leggende metropolitane e falsi miti e implementeremo DDD mostrando poche slide e tanto codice.
Never Mind the Bollocks: here's the Domain Driven Design
1. NEVER MIND THE BOLLOCKS:
HERE’S THE
Domain Driven Design
Andrea Saltarello
C.T.O. @ managed/designs
http://blogs.ugidotnet.org/pape
http://twitter.com/andysal74
http://creativecommons.org/licenses/by-nc-nd/2.5/
2. Kudos
Grazie a:
• Trenitalia
• Depeche Mode
• Joy Division
Perché, avendo viaggiato su un treno che aveva
oltre 1h di ritardo, ho potuto migliorare un po’
le slide ed ascoltare tanta buona musica
3. Andrea Saltarello! Chi era costui?
1. C.E.O. di Managed Designs, alla ricerca della
«sostenibilità dello sviluppo software»
– Il cliente «deve» essere soddisfatto e pagare
– Il fornitore «deve» avere un margine ragionevole
– Il team «deve» essere soddisfatto del proprio lavoro
2. Fondatore e presidente di UGIdotNET: ho bisogno
di condividere esperienze a causa del bullet
precedente
3. (Co)Autore (insieme a Dino) di .NET: Architecting
Applications for the Enterprise di Microsoft Press, il
mio giornale di bordo nel quale (nel 2008 e 2014)
ho cercato di «sintetizzare» i punti 1 e 2
4. Leggere attentamente le avvertenze…
(Quasi) Tutte le demo saranno basate su:
• NSK, un framework di e-commerce sviluppato in
bottega e scaricabile qui con licenza open source.
#legacy
• Merp, un «Micro» ERP sviluppato in bottega e
scaricabile qui con licenza open source.
N.B.: entrambi sono come il galeone di Dylan Dog,
quindi mai terminati e non tutti i check-in sono come
la caramella Polo (cioè «riusciti col buco» )
5. Cos’è DDD?
Domain Driven Design:
• Non è una metodologia
• Non è una architettura
• Non è un silver bullet
• è un approccio strategico alla realizzazione del
software pensato per contrastare la complessità
insita nel farlo; gli asset strategici sono:
– Aggregate
– Bounded Context
– (Eventi)
– Ubiquitous Language
6. Ubiquitous Language
E’ il linguaggio utilizzato nelle discussioni tra tutti
i partecipanti al progetto, nei diagrammi, nella
documentazione e nel codice, diventando così
comune a tutti gli attori che partecipano alla
realizzazione del software
Attenzione ai dialetti!
7. Ubiquitous Language: falsi positivi
Nella sua definizione di segno linguistico, Ferdinand
de Saussure distingue:
• un elemento formale, o esterno, costituito dal
significante,
• e un elemento intrinseco, concettuale, costituito
dal significato.
Qualsiasi segno esiste solo grazie alla relazione tra
significante e significato. In altre parole, il
significante è la forma, fonica o grafica, utilizzata per
richiamare l'immagine che, nella nostra mente, è
associata a un determinato concetto, o significato.
8. Bounded Context
Un Bounded Context è un contesto all’interno
del quale è valido uno specifico ubiquitous
language
Un sistema è quindi una composizione di contesti
differenti (es: web store, accountability,
delivery&shipment …), comunicanti tra di loro
mediante apposite Context Map
L’esistenza dei bounded context permette scelte
ad hoc per ognuno di essi
9. Aggregate
All’interno di un BC, interagiscono unità
funzionali autonome chiamate Aggregate: ogni
aggregate rappresenta l’artefatto che riproduce
«both data and behaviour» di un concetto
«importante» esistente nel contesto stesso.
• Il sistema coordina il lavoro degli aggregate
• L’insieme degli aggregate rappresenta il
Domain Model
10. Andrea vs. DDD, A.D. 2004
Tutto chiaro: un sistema è una composizione di
Bounded Context all’interno dei quali
interagiscono, coordinati dal sistema stesso,
degli Aggregate che rappresentano i significati
espressi nell’Ubiquitous Language.
Fantastico! Figata!
Ho un solo piccolo problema: come implemento
‘sta roba?
13. DDD: architettura «Blue Book»
• è una layered architecture
• i layer Presentation e Infrastructure
compaiono «per sport» nel diagramma
• i layer Application e Domain costituiscono
quella che tipicamente chiamiamo «business
logic»
– Domain: logica invariante rispetto ai casi d’uso
– Application: logica specifica ai casi d’uso
14. Domain layer: Key Concepts
• Il Domain Layer contiene la domain logic ed è
composto da
– Model: Entità (identità e stato) e Valori (solo stato)
– Servizi
• Il Model è «both data and behaviour» (cit.)
• La persistenza del Model è gestita da Repository
• Le istanze delle entità di dominio sono costruite da
Factory
• Entità e Valori a runtime formano dei grafi di oggetti. I
grafi dotati di “dignità propria” sono chiamati
Aggregate e il sistema (es: i Repository) si “impegna” a
gestirli correttamente ed atomicamente
15. Da 0 ad Aggregate
• E' un insieme di elementi raggruppati in un’unità
logica, quindi un grafo di oggetti
• Ha come radice l'entità principale dell'aggregato
• La radice è l’unico elemento che può essere
referenziato fuori dai confini dell’aggregato
• Non è possibile agire direttamente sugli elementi
senza passare dalla radice dell'aggregato
• L’aggregate ha la responsabilità di implementare
la propria logica
16. Non stiamo
modellando la realtà
assoluta, bensì un
modello utile
all’interno di un
bounded context
Per intenderci: la
mappa in alto è
“sbagliata”, però
“funziona”
17. Application Layer: in teoria
Application Layer: defines the jobs the software is
supposed to do and directs the expressive domain
objects to work out problems. The tasks this layer is
responsible for are meaningful to the business or
necessary for interaction with the application layers
of other systems. This layer is kept thin. It does not
contain business rules or knowledge, but only
coordinates tasks and delegates work to
collaborations of domain objects in the next layer
down. It does not have state reflecting the business
situation, but it can have state that reflects the
progress of a task for the user or the program.
[DDD, ]
18. Application Layer: in pratica
E’ un catalogo di servizi in grado di effettuare il
mesh della logica presente nel domain layer
esponendola alla applicazione (es: presentation
layer) in una forma ad… Alta digeribilità.
19. DDD vs Real World
Avere a disposizione un domain layer «smart» è
bello, ma costoso:
• Materializzazione degli oggetti
• Mesh della business logic
Tipicamente, si finisce per passare la vita a «fare
DTO»:
• Application Layer <-> Presentation Layer
• Domain Layer <-> Application Layer
20. Layered Expression Trees (LET idiom)
Facciamo un gioco: invece di definire un «botto» di
DTO, facciamo che layer e servizi si scambino degli
IQueryable<YourDomainEntity>, facendo
«emergere» la query e specificando la proiezione
solo all’ultimo momento?
L’espressione «Capra e cavoli» vi dice niente?
N.B.: «botto» è un ordine di grandezza del S.I. Kilo-
>Mega->Giga->Tera->Peta->Botto
21. Ubiquitous Language <3 LET
LET aumenta la pervasività dell’Ubiquitous Language nel
codice:
recommendedProducts = (from p in CatalogServices.GetAvailableProductsOnSale()
orderby p.UnitsInStock descending
select new ProductDescriptor
{
Id = p.Id,
Name = p.Name,
UnitPrice = p.UnitPrice,
UnitsInStock = p.UnitsInStock,
}).Take(3);
Questa query è «quasi» scritta nel linguaggio del Domain
Expert (ma vedremo che si può far meglio)
22. Debriefing Domain Model
A single model cannot be appropriate for
reporting, searching and transactional
behaviours
(Greg Young)
Domain Model funziona, ma richiede un po’ di
compromessi: è possibile implementare DDD
con una architettura differente?
24. Command Query Responsibility Segregation
Command and Query Responsibility Segregation (CQRS)
originated with Bertrand Meyer’s Command and Query
Separation Principle. Wikipedia defines the principle as:
It states that every method should either be a command that
performs an action, or a query that returns data to the caller, but
not both.
Command and Query Responsibility Segregation uses the same
definition of Commands and Queries that Meyer used and
maintains the viewpoint that they should be pure. The
fundamental difference is that in CQRS objects are split into two
objects, one containing the Commands one containing the
Queries.
[Fonte: http://cqrsinfo.com/documents/cqrs-introduction/ ]
26. L’architettura di CQRS
1. «Fare CQRS» significa separare lo stack di
lettura da quello che provoca i cambi di stato
del sistema.
2. Distinguere lo stack di lettura da quello
«comportamentale» permette di utilizzare
per ognuno di essi una architettura ad hoc
3. I comportamenti del sistema sono espressi
mediante le azioni (a.k.a. Command) che
esso può effettuare
27. Lo stack di CQRS
1. L’utente Un attore chiede al sistema
l’esecuzione di un command
2. Il command modifica lo stato del sistema
3. Il read model permette all’utente di
conoscere il nuovo stato del sistema
28. CQRS: lo stack di lettura
• Plain SQL
• (Micro) O/RM
• LET (Layered Expression Trees)
• Servizi
29. CQRS <3 LET
Quale manager di una business unit, desidero avviare la
procedura di recupero credito per tutti gli insoluti di mia
competenza #ubiquitouslanguage #nuffsaid
Database.OutgoingInvoices.
.PerBusinessUnit(businessUnitId)
.ExpiredOnly()
.Select(i => new {InvoiceNumber = i.Number, CustomerId =
i.Customer.Id})
.AsParallel()
.ForAll(i => bus.Send(new
CollectDebtCommand(i.InvoiceNumber, i.CustomerId)));
P.S.: Lo avevo detto che avremmo migliorato
30. CQRS feat. Transaction Script
Transaction Script
[P of EAA, 110]
Organizes business logic by procedures where
each procedure handles a single request from
the presentation.
In pratica, modelliamo i comandi come funzioni,
che saranno invocate dall’application layer
31. Entity-less CQRS
«Gli offri una mano, e si prende tutto il braccio»
(detto popolare)
Se posso modellare lo stack «comportamentale»
senza la necessità di renderlo capace di leggere
il nuovo stato del sistema, potrei rinunciare tout
court ad una rappresentazione basata su entità.
Sticazzi E perché dovrei farlo?
32. (Domain) Events
It really became clear to me in the last couple of years that
we need a new building block and that is the Domain
Event.
Eric Evans
An event is something that has happened in the past.
Greg Young
A domain event … captures the memory of something
interesting which affects the domain
Martin Fowler
33. CQRS feat. Domain Events
Terzo principio della dinamica: ad ogni azione
corrisponde una reazione un evento
«CTRL+Z principle»: Invece di focalizzarci sull’ultimo
stato noto del sistema, potremmo osservare gli
eventi che lo hanno determinato: in questo modo,
potrò risalire allo stato del sistema in ogni momento
di interesse, oppure produrre nuove proiezioni
JobOrderCreated InvoiceIssuedJobOrderExtended JobOrderClosed
34. CQRS vs. eventi
Ok, però io ho bisogno di sapere se la fattura sia
stata pagata o il bilancio di una commessa.
Come faccio?
• Ricostruisco lo stato ripercorrendo l’intero log
degli eventi (lento, ma potrei usare degli
snapshot)
• Mantengo un database «read friendly»
35. CQRS/ES to the rescue
1. L’applicazione esegue un command
2. il command cambia lo stato del sistema ed invia
al sistema stesso un evento in qualità di notifica
3. Gli eventi vengono notificati ai sottoscrittori ad
essi interessati quali:
1. Gestori di workflow (a.k.a. «Saghe»), che
eseguiranno altri command
2. Denormalizzatori, che aggiorneranno il read model
P.S.: consiglio: facciamo fare le notifiche ad un
Mediator (a.k.a. «Bus»)
37. On a technology side…
Abbiamo bisogno di un bus e di un event store:
build or buy?
• Event Store:
– SQLQualcosa
– MongoDB
– RavenDB
– …
• Bus:
– NEventStore
– NServiceBus
– …
Il mio “consiglio”? Buy #tuttalavita
38. The “Buy” Side of the Force
SQLQualcosa MongoDB RavenDB
• Skillset diffuso
• Tool per “LaQualunque”
• Both On-Premise &
cloud
• Gratis
• “Gira” su Linux
• Both On-Premise &
cloud
• Schemaless
• LINQ provider cazzuto
• Supporto TX+DTC
• Schemaless
MSMQ NEventStore NServiceBus
• AHAHAHAHAHAHAHAH • Gratis
• FOSS
• Stack DDD/CQRS/ES
completo
• Opzioni di
configurazione
• Supporto notifiche
39. Bibliografia
[DDD] Domain Driven Design, Eric Evans ,
Addison-Wesley
What I've learned about DDD since the book,
Eric Evans, InfoQ
[NAAE] Microsoft .NET: Architecting
Applications for the Enterprise (2° ed.),
Andrea Saltarello & Dino Esposito, Microsoft
Press
[NSK] NSK, http://nsk.codeplex.com
[MERP] Merp, https://naa4e.codeplex.com/