SlideShare una empresa de Scribd logo
1 de 39
Descargar para leer sin conexión
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/
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 
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 
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» )
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
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!
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.
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
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
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? 
BLUE BOOK
2004: a Domain Odissey
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
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
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
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”
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, ]
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à.
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
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
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)
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?
CQRS
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/ ]
Command Query Responsibility Segregation
Query Command
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
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
CQRS: lo stack di lettura
• Plain SQL
• (Micro) O/RM
• LET (Layered Expression Trees)
• Servizi
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 
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
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?
(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
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
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»
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»)
Read
Model
Application
Layer
Domain
layer
Event
store
QUERY
COMMAND
Bus
EVENT Handler
Handler
Handler
Snapshot
DB
CQRS/ES in a nutshell
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
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
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/

Más contenido relacionado

Destacado

How I did it (in .NET): idiomatic Domain Driven Design
How I did it (in .NET): idiomatic Domain Driven DesignHow I did it (in .NET): idiomatic Domain Driven Design
How I did it (in .NET): idiomatic Domain Driven DesignAndrea Saltarello
 
Implementing Event Sourcing in .NET
Implementing Event Sourcing in .NETImplementing Event Sourcing in .NET
Implementing Event Sourcing in .NETAndrea Saltarello
 
Using the Actor Model with Domain-Driven Design (DDD) in Reactive Systems - w...
Using the Actor Model with Domain-Driven Design (DDD) in Reactive Systems - w...Using the Actor Model with Domain-Driven Design (DDD) in Reactive Systems - w...
Using the Actor Model with Domain-Driven Design (DDD) in Reactive Systems - w...Lightbend
 
The final words about software estimation
The final words about software estimationThe final words about software estimation
The final words about software estimationAlberto Brandolini
 

Destacado (6)

How I did it (in .NET): idiomatic Domain Driven Design
How I did it (in .NET): idiomatic Domain Driven DesignHow I did it (in .NET): idiomatic Domain Driven Design
How I did it (in .NET): idiomatic Domain Driven Design
 
Implementing Event Sourcing in .NET
Implementing Event Sourcing in .NETImplementing Event Sourcing in .NET
Implementing Event Sourcing in .NET
 
Transactions redefined
Transactions redefinedTransactions redefined
Transactions redefined
 
Using the Actor Model with Domain-Driven Design (DDD) in Reactive Systems - w...
Using the Actor Model with Domain-Driven Design (DDD) in Reactive Systems - w...Using the Actor Model with Domain-Driven Design (DDD) in Reactive Systems - w...
Using the Actor Model with Domain-Driven Design (DDD) in Reactive Systems - w...
 
Event storming recipes
Event storming recipesEvent storming recipes
Event storming recipes
 
The final words about software estimation
The final words about software estimationThe final words about software estimation
The final words about software estimation
 

Similar a Never Mind the Bollocks: here's the Domain Driven Design

Layered Expression Trees feat. CQRS
Layered Expression Trees feat. CQRSLayered Expression Trees feat. CQRS
Layered Expression Trees feat. CQRSAndrea Saltarello
 
Code Contracts and Generics: implementing a LINQ-enabled Repository
Code Contracts and Generics: implementing a LINQ-enabled RepositoryCode Contracts and Generics: implementing a LINQ-enabled Repository
Code Contracts and Generics: implementing a LINQ-enabled RepositoryAndrea Saltarello
 
Build a LINQ-enabled Repository
Build a LINQ-enabled RepositoryBuild a LINQ-enabled Repository
Build a LINQ-enabled RepositoryAndrea Saltarello
 
UI composition @ dotNetMarche
UI composition @ dotNetMarcheUI composition @ dotNetMarche
UI composition @ dotNetMarcheMauro Servienti
 
ios 8 - parte 1 - intro - ita
ios 8 - parte 1 - intro - itaios 8 - parte 1 - intro - ita
ios 8 - parte 1 - intro - itaDario Rusignuolo
 
Approccio Pratico al Domain Driven Design
Approccio Pratico al Domain Driven DesignApproccio Pratico al Domain Driven Design
Approccio Pratico al Domain Driven DesignLuca Milan
 
Sencha touch: Sviluppare un'app - 4° parte
Sencha touch: Sviluppare un'app - 4° parteSencha touch: Sviluppare un'app - 4° parte
Sencha touch: Sviluppare un'app - 4° parteGiuseppe Toto
 
Domain Driven Design e CQRS
Domain Driven Design e CQRSDomain Driven Design e CQRS
Domain Driven Design e CQRSManuel Scapolan
 
Introduzione al Domain Driven Design (DDD)
Introduzione al Domain Driven Design (DDD)Introduzione al Domain Driven Design (DDD)
Introduzione al Domain Driven Design (DDD)DotNetMarche
 
C#, imparare a programmare e sopravvivere
C#, imparare a programmare e sopravvivereC#, imparare a programmare e sopravvivere
C#, imparare a programmare e sopravvivereMatteo Valoriani
 
Community Tour 2009 Windows Azure Overview
Community Tour 2009 Windows Azure OverviewCommunity Tour 2009 Windows Azure Overview
Community Tour 2009 Windows Azure OverviewFabio Cozzolino
 
Entity Framework 4.0 vs NHibernate
Entity Framework 4.0 vs NHibernateEntity Framework 4.0 vs NHibernate
Entity Framework 4.0 vs NHibernateManuel Scapolan
 
Repository pattern slides v1.1
Repository pattern slides v1.1Repository pattern slides v1.1
Repository pattern slides v1.1Christian Nastasi
 
Blockchain e AI: verso una nuova finanza
Blockchain e AI: verso una nuova finanzaBlockchain e AI: verso una nuova finanza
Blockchain e AI: verso una nuova finanzaAlessandro Greppi
 
Cqrs and IoT: a match made in heaven
Cqrs and IoT: a match made in heavenCqrs and IoT: a match made in heaven
Cqrs and IoT: a match made in heavenCarmine Ingaldi
 

Similar a Never Mind the Bollocks: here's the Domain Driven Design (20)

Layered Expression Trees feat. CQRS
Layered Expression Trees feat. CQRSLayered Expression Trees feat. CQRS
Layered Expression Trees feat. CQRS
 
Code Contracts and Generics: implementing a LINQ-enabled Repository
Code Contracts and Generics: implementing a LINQ-enabled RepositoryCode Contracts and Generics: implementing a LINQ-enabled Repository
Code Contracts and Generics: implementing a LINQ-enabled Repository
 
Build a LINQ-enabled Repository
Build a LINQ-enabled RepositoryBuild a LINQ-enabled Repository
Build a LINQ-enabled Repository
 
UI composition @ dotNetMarche
UI composition @ dotNetMarcheUI composition @ dotNetMarche
UI composition @ dotNetMarche
 
ios 8 - parte 1 - intro - ita
ios 8 - parte 1 - intro - itaios 8 - parte 1 - intro - ita
ios 8 - parte 1 - intro - ita
 
Approccio Pratico al Domain Driven Design
Approccio Pratico al Domain Driven DesignApproccio Pratico al Domain Driven Design
Approccio Pratico al Domain Driven Design
 
m-v-vm @ UgiAlt.Net
m-v-vm @ UgiAlt.Netm-v-vm @ UgiAlt.Net
m-v-vm @ UgiAlt.Net
 
Sencha touch: Sviluppare un'app - 4° parte
Sencha touch: Sviluppare un'app - 4° parteSencha touch: Sviluppare un'app - 4° parte
Sencha touch: Sviluppare un'app - 4° parte
 
Domain Driven Design e CQRS
Domain Driven Design e CQRSDomain Driven Design e CQRS
Domain Driven Design e CQRS
 
Introduzione al Domain Driven Design (DDD)
Introduzione al Domain Driven Design (DDD)Introduzione al Domain Driven Design (DDD)
Introduzione al Domain Driven Design (DDD)
 
Kotlin hexagonal-architecture
Kotlin hexagonal-architectureKotlin hexagonal-architecture
Kotlin hexagonal-architecture
 
UI Composition
UI CompositionUI Composition
UI Composition
 
C#, imparare a programmare e sopravvivere
C#, imparare a programmare e sopravvivereC#, imparare a programmare e sopravvivere
C#, imparare a programmare e sopravvivere
 
Repository pattern
Repository patternRepository pattern
Repository pattern
 
Community Tour 2009 Windows Azure Overview
Community Tour 2009 Windows Azure OverviewCommunity Tour 2009 Windows Azure Overview
Community Tour 2009 Windows Azure Overview
 
Entity Framework 4.0 vs NHibernate
Entity Framework 4.0 vs NHibernateEntity Framework 4.0 vs NHibernate
Entity Framework 4.0 vs NHibernate
 
ORM - Introduzione
ORM - IntroduzioneORM - Introduzione
ORM - Introduzione
 
Repository pattern slides v1.1
Repository pattern slides v1.1Repository pattern slides v1.1
Repository pattern slides v1.1
 
Blockchain e AI: verso una nuova finanza
Blockchain e AI: verso una nuova finanzaBlockchain e AI: verso una nuova finanza
Blockchain e AI: verso una nuova finanza
 
Cqrs and IoT: a match made in heaven
Cqrs and IoT: a match made in heavenCqrs and IoT: a match made in heaven
Cqrs and IoT: a match made in heaven
 

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? 
  • 12. 2004: a Domain Odissey
  • 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?
  • 23. CQRS
  • 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/ ]
  • 25. Command Query Responsibility Segregation Query Command
  • 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/