loosely coupled complexity - unleash the power of your domain model
DESCRIPTION
Common software architectures are full of well-established assumptions. But some of them are flawed, no longer valid or relevant. Changing the rules of the game using DDD, CQRS and Event Sourcing can lead to systems which are more scalable, maintainable and performing. And which are fun to code as well.TRANSCRIPT
Loosely Coupled Complexity
Loosely Coupled Complexity
Unleash the power of your Domain Model using CQRS & Event SourcingUnleash the power of your Domain Model using CQRS & Event Sourcing
[email protected]@avanscopertas.it
About meIn the IT field since ZX SpectrumGenerally in large scale projects (I might be biased)Freelance consultant: NotOnlyCodeTrainer (Freelance & Skills Matter + Zenika)Technical WriterBlogger: http://ziobrando.blogspot.comTwitter: ziobrando
My e-mail: [email protected]
© Alberto Brandolini 2009
@avanscoperta
www.avanscoperta.it
avanscoperta.wordpress.com
@avanscoperta
www.avanscoperta.it
avanscoperta.wordpress.com
Questi 3 tipi hanno qualcosa di veramente interessante da dire...
© Alberto Brandolini - 2010
Cosa c’è che non va?Cosa c’è che non va?
UIUIUIUIR
em
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Applic
ati
on S
erv
ices
Applic
ati
on S
erv
ices
Applic
ati
on S
erv
ices
Applic
ati
on S
erv
ices
DTODTODTODTO
DTODTODTODTO
OR
MO
RM
OR
MO
RM
niente
Thank [email protected]
http://ziobrando.blogspot.comtwitter: ziobrando
- Quale gobba?
Quante assunzioni stanno guidando le nostre decisioni?
© Alberto Brandolini - 2010
Proviamo ancora...Proviamo ancora...
UIUIUIUIR
em
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Applic
ati
on S
erv
ices
Applic
ati
on S
erv
ices
Applic
ati
on S
erv
ices
Applic
ati
on S
erv
ices
DTODTODTODTO
DTODTODTODTO
OR
MO
RM
OR
MO
RM
Anaemic Domain Model
i DTO?
Ottimizzazione query su ORM
Tempo di sviluppo
Testabilità
...
Abbiamo veramente bisogno di...
un Domain Model?
un Database?
transazioni?
un Object Relational Mapper?
DTO?
Anaemic Domain Model
Non tutti i regali sono necessariamente
graditi...
Non tutti i regali sono necessariamente
graditi...
Vantaggi dell’Anaemic Domain Model
1) Il codice business è localizzato in un solo posto:Più facile da leggere per sviluppatori giovani non familiari con OOP.
Spiacente ...non c’è il numero 2 :-(
Svantaggi dell’Anemic Domain Model
Triste come un pasto in ospedale
Triste come un pasto in ospedale
difficile da mateneredifficile da testare
alimenta la duplicazione
difficile da mateneredifficile da testare
alimenta la duplicazione
avanscoperta
Progettate la vistra applicazione partendo dal data model
Create il vostro domain model via reverse engineering
Dichiarate di fare TDD e cominciate a testare le vostre classi di dominio
In particolare i getter ed i setters
Quindi, testate la logica con i test d’Integrazione, ed impantanatevi con i dati di test.
Dichiarate ufficialmente che TDD non porta alcun vantaggio e che vi fa solo rallentare.
Commentate i tests nel vostro script di Build - Continuous Integration
Continuate a lamentarvi
Come farsi del male da soliCome farsi del male da soli
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Non farò più il reverse engineering del data model per creare un domain model
Come dovremmo implementare un Domain Model?
Fate in modo che il codice parli lo Ubiquitous Language
Proteggete il vostro modello con dei Bounded Contexts
Usate gli Aggregati come unità di consistenza nel vostro domain model
Il comportamento dovrebbe risiedere nel Domain Model
Anemic Domain Model
Rich domain modelRich domain model
© Alberto Brandolini - 2010
TDD e DDDTDD e DDDRiscritture frequentiRiscritture frequenti
Exploratory codingExploratory coding
Domain Objects minimali
Domain Objects minimali
Focus sugli Unit TestsFocus sugli Unit Tests
Tiny Domain ObjectsTiny Domain Objects
Tiny Domain ObjectsTiny Domain Objects
Cicli corti e frequenti
Cicli corti e frequenti
Codice autoesplicativoCodice autoesplicativo
Feedback rapidoFeedback rapido
Libertà di cambiareLibertà di cambiare
© Alberto Brandolini - 2010
Aggregate
Un gruppo di oggetti naturalmente viciniUnità di consistenza nel domain model
modificati nella stessa transazionecancellati insiemetrasferiti insieme
© Alberto Brandolini - 2010
Aggregati multipli
© Alberto Brandolini - 2010
Ma la duplicazione non era il male?
Ma la duplicazione non era il male?
- Se pensiamo ai “dati” allora ...c’è duplicazione
- Se pensiamo al “comportamento” allora alcuni oggetti
non sono la stessa cosa
- stabilire i confini degli aggregati rende il nostro sistema
- strettamente consistente all’interno degli aggregate boundaries
- eventualmente consistente al di fuori dei confini dell’aggregato
© Alberto Brandolini - 2010
Alla fine è piuttosto semplice
© Alberto Brandolini - 2010
Perchè complicarsi la vita?
© Alberto Brandolini - 2010
Una volta che l’accoppiamento tra gli aggregati è ridotto... potrei anche pensare di scegliere una strategia di persistenza differente per ogni aggregato...
Hmm...Hmm...
© Alberto Brandolini - 2010
dalla cara vecchia architettura...
dalla cara vecchia architettura...
UIUIUIUIR
em
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Applic
ati
on S
erv
ices
Applic
ati
on S
erv
ices
Applic
ati
on S
erv
ices
Applic
ati
on S
erv
ices
DTODTODTODTO
DTODTODTODTO
OR
MO
RM
OR
MO
RM
© Alberto Brandolini - 2010
UIUIUIUIR
em
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
DTODTODTODTO
DTODTODTODTO
OR
MO
RM
OR
MO
RM
La visione DDD classica
La visione DDD classica
boundbounded ed contex
contextsts
boundbounded ed contex
contextsts
aggregat
aggregate e boundari
boundarieses
aggregat
aggregate e boundari
boundariesesthin thin
application
application layerlayer
thin thin
application
application layerlayer
© Alberto Brandolini - 2010
Portiamo i Domain Objects alla UI?
Portiamo i Domain Objects alla UI?
- I DTO non piacciono a nessuno...
- Alcuni tool lo permettono! (hey, c’è una camicia hawaiana in regalo!!)
- Il delirio della validazione
- Gli oggetti a 2 stati
- la tentazione del Framework
© Alberto Brandolini - 2010
Come implementereste queste?
Come implementereste queste?
As aAs a Marketing Office Marketing OfficeI want toI want to assign discount assign discount points to customer on points to customer on every purchaseevery purchaseIn order toIn order to enable more enable more deals in the futuredeals in the future
As aAs a Marketing Office Marketing OfficeI want toI want to assign discount assign discount points to customer on points to customer on every purchaseevery purchaseIn order toIn order to enable more enable more deals in the futuredeals in the future
As aAs a Sales Office Sales OfficeI want toI want to ship order on ship order on purchase commandpurchase commandIn order toIn order to deliver deliver purchased goods to the purchased goods to the customercustomer
As aAs a Sales Office Sales OfficeI want toI want to ship order on ship order on purchase commandpurchase commandIn order toIn order to deliver deliver purchased goods to the purchased goods to the customercustomer
© Alberto Brandolini - 2010
Eventi e coordinamento fra aggregati
Eventi e coordinamento fra aggregati
- Operazione che coinvolgono più aggregati non dovrebbero essere nella stessa Unit of Work
- La comunicazione fra aggregati è intrisecamente asincrona
- Domain Events come meccanismo di comunicazione
- dall’esterno
- fra aggregati
© Alberto Brandolini - 2010
Domain EventDomain Event
- nello Ubiquitous Language, sono Azioni Completate: verbi al passato.
© Alberto Brandolini - 2010
Rispondere asincronamente agli eventi
Rispondere asincronamente agli eventi
- Non dimentichiamo: il legame vero tra le azioni è definito dal business!!!
a qualcuno ricorda SOA?
...proviamo a disegnare le cose diversamente e
pensare alla “granularità dei servizi”
Command/Query Responsibility Segregation
Command/Query Responsibility Segregation
perché trovare un compromesso?
© Alberto Brandolini - 2010
Partendo dal piccolo...Partendo dal piccolo...
- Command/Query Separation era un principio OOD incluso in DDD- accessors non dovrebbero avere side
effects
- mutators non dovrebbero ritornare un valore - (con ll’eccezione di this in alcuni casi)
© Alberto Brandolini - 2010
!Di solito indirizzati ad entità singoleil comportamento è importante la Flessibilità è importante
Command
© Alberto Brandolini - 2010
?Grosse quantità di datiNon c’è comportamentole Prestazioni sono importantiDisponibili numerosi componenti off-the shelf
Query
?
!UIUIUIUI
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
DTODTODTODTO
DTODTODTODTO
OR
MO
RM
OR
MO
RM
da questo...da questo...
?
!UIUIUIUI
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
OR
MO
RM
OR
MO
RM
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Thin
Read
Layer
Thin
Read
Layer
Thin
Read
Layer
Thin
Read
Layer
DTODTODTODTO
DTODTODTODTO
...a questo
...a questo
?
!Un percorso separato per
comandi inviati al Domain Model
Un percorso separato per recuperare Dati
© Alberto Brandolini - 2010
? QueryingQuerying-Date un’occhiata ai vostri
utenti, cosa interessa loro veramente?
-Non è cercare, è trovare
-Non è il refresh, stanno cercando eventi
© Alberto Brandolini - 2010
? StalenessStaleness- È veramente un problema?
- Importa veramente se i dati sono...
- di 20 secondi fa?
- O di 10 minuti?
- ... chi siamo noi per decidere questa cosa?
- ... puoi tenere sincronizzata una stampa?
- o un PowerPoint?
© Alberto Brandolini - 2010
? Sono solo datiSono solo dati
- Non c’è comportamento in quello che vediamo.
- Abbiamo veramente bisogno di oggetti?
© Alberto Brandolini - 2010
? Query-Only ArchitectureQuery-Only Architecture
- Sono solo dati: no comportamento...
- => perché non andare dritti sul database?
- Non c’è accoppiamento tra le schermate della UI...
- => Abbiamo veramente bisogno della referential integrity?
- => Perché non usare una table-per-UI-view strategy, calcolata in background?
- Cosa stiamo già facendo con il search model e con la cache?
© Alberto Brandolini - 2010
? Anche i dati stale possono
Anche i dati stale possono
- ... fornire informazioni utili per la validazione preliminare dei comandi
- => meno comandi che falliscono
© Alberto Brandolini - 2010
! ...meno comandi che falliscono
...meno comandi che falliscono
- Se la maggio parte dei nostri comandi avrà successo...
- ... c’è veramente bisogno di rispondere immediatamente o sullo stesso canale?
- Perché non qualcosa come: “Thank you for your order, your confirmation e-mail will arrive shortly”?
© Alberto Brandolini - 2010
! Catturare le intenzioni dell’utente
Catturare le intenzioni dell’utente
- Sappiamo realmente cosa l’utente vuole fare con la nostra applicazione?
- Stiamo realmente supportando i nostri utenti?
- Chi si sta facendo carico della complessità?
- ... non possiamo fare qualcosa di più intelligente che semplicemente mostrare dati grezzi?
- ...un sacco di carico sul versante dati è sostanzialmente inutile
© Alberto Brandolini - 2010
! Commands != Entities
Commands != Entities
- Non c’è molto in comune...
- per quale motivo devo mostrarle all’utente?
© Alberto Brandolini - 2010
! Write-only modelWrite-only model- Il domain model non è usato per recuperare o
mostrare dati.
- Le relazioni tra entità orientate al recupero dei dati ... non sono più necessarie
- Il Domain Model è sempre in uno stato consistente (dalla Factory alla Garbage Collection)
- Non è necessaria la validazione sul Domain Model (comandi sono validati prima)
- Testare il Domain Model diventa ancora più semplice
© Alberto Brandolini - 2010
! Persisting the modelPersisting the model
- Abbiamo veramente bisogno di rendere persistenti tutti i dati?
- Abbiamo veramente bisogno di renderli persistenti su un supporto Relazionale?
- (ricordate, non stiamo facendo query sul modello...)
?
!UIUIUIUI
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
OR
MO
RM
OR
MO
RM
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Thin
Read
Layer
Thin
Read
Layer
Thin
Read
Layer
Thin
Read
Layer
DTODTODTODTO
CommandCommandss
CommandCommandss
?
!UIUIUIUI
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
OR
M?
OR
M?
OR
M?
OR
M?
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Thin
Read
Layer
Thin
Read
Layer
Thin
Read
Layer
Thin
Read
Layer
DTODTODTODTO
voilàvoilà
publish publish subscribesubscribepublish publish
subscribesubscribeSpecialized
Specialized
data model
data model
Specialized
Specialized
data model
data model
does it really
does it really
need to be
need to be relational?
relational?
does it really
does it really
need to be
need to be relational?
relational?
CommandCommandss
CommandCommandss
Eventu
all
Eventu
all
yyEventu
all
Eventu
all
yy
© Alberto Brandolini - 2010
! un interessante side effect
un interessante side effect- ... meno collections ...
- => meno impatto sulla memoria
- => meno Garbage Collection
- su alcuni sistemi, il Domain Model è sempre disponibile
The paper-based system
Molti tipi di azienda nascono prima dei computersLe transazioni non sono un problema bisinessI Dati possono essere disallineati...capitaCHIEDIAMO al Business
Molti tipi di azienda nascono prima dei computersLe transazioni non sono un problema bisinessI Dati possono essere disallineati...capitaCHIEDIAMO al Business
Event SourcingEvent Sourcing
© Alberto Brandolini - 2010
! Quindi ...cosa fa il nostro Domain Model?
Quindi ...cosa fa il nostro Domain Model?
- fondamentalmente risponde a messaggi autocontenuti provenienti dall’esterno...
- eventi dalla UI o da sorgenti esterne
© Alberto Brandolini - 2010
! La singola sorgente di verità
La singola sorgente di verità
- Un tempo era la carta...
- ora sono gli Eventi
?
!UIUIUIUI
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
Ap
plic
ati
on S
erv
ices
OR
M ?
OR
M ?
OR
M ?
OR
M ?
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Rem
ote
faca
de
Thin
Read
Layer
Thin
Read
Layer
Thin
Read
Layer
Thin
Read
Layer
DTODTODTODTO
voilàvoilà
publish publish subscribesubscribepublish publish
subscribesubscribe
EventsEventsEventsEvents Events
Events
Events
Events
© Alberto Brandolini - 2010
! Dobbiamo tenere lo stato nelle Entities?
Dobbiamo tenere lo stato nelle Entities?
- Abbiamo tutte le informazioni necessarie nella Event Queue
- SINGLE SOURCE of TRUTH
- Cos’è un Aggregato? qualcosa che cambia il suo stato in risposta ad eventi
- ...secondo il nostro livello attuale di comprensione del sistema
© Alberto Brandolini - 2010
! Aggregati ed eventiAggregati ed eventi
Gli aggregati tengono traccia degli eventi e derivano il proprio comportamento di conseguenza
© Alberto Brandolini - 2010
! Che succede se...Che succede se...- deriviamo lo stato degli Aggregati dalla
sequenza degli eventi che sono avvenuti in un sistema?
- => Possiamo avere feaures retroattive...
- => Possiamo rispondere SI ad un sacco di richieste strane/interessanti che arrivano dal business.
- => Riprodurre bug?
© Alberto Brandolini - 2010
!
Gli aggregati disaccoppiati permettono semplificazioni nello sviluppo
Gli aggregati disaccoppiati permettono semplificazioni nello sviluppo
La terra delle opportunitàLa terra delle opportunità
Polyglot persistencePolyglot persistence
migliore scalabilitàmigliore scalabilità
Polyglot persistencePolyglot persistencePolyglot persistence
SOA indoloreSOA indolore
Applicazioni riavvolgibiliApplicazioni riavvolgibili
Una cosa alla voltaNon è detto che abbiate
bisogno di tuttoOgni step è un miglioramento
Anche in piccole architetture
...Mettiamo in discussione
un’assunzione alla volta
© Alberto Brandolini - 2010
ReferencesReferenceshttp://groups.google.com/group/dddcqrs
http://cqrs.wordpress.com/
http://www.infoq.com/interviews/Architecture-Eric-Evans-Interviews-Greg-Young
http://www.udidahan.com/2009/12/09/clarified-cqrs/
http://www.infoq.com/presentations/Command-Query-Responsibility-Segregation
http://www.infoq.com/presentations/SOA-Business-Autonomous-Components
http://martinfowler.com/eaaDev/EventSourcing.html
http://skillsmatter.com/podcast/design-architecture/architectural-innovation-eventing-event-sourcing
Thank [email protected]
http://ziobrando.blogspot.comtwitter: ziobrando