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

1,053 views
902 views

Published on

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.

Published in: Software

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

  1. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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? 
  11. 11. BLUE BOOK
  12. 12. 2004: a Domain Odissey
  13. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 23. CQRS
  24. 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. 25. Command Query Responsibility Segregation Query Command
  26. 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. 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. 28. CQRS: lo stack di lettura • Plain SQL • (Micro) O/RM • LET (Layered Expression Trees) • Servizi
  29. 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. 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. 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. 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. 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. 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. 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»)
  36. 36. Read Model Application Layer Domain layer Event store QUERY COMMAND Bus EVENT Handler Handler Handler Snapshot DB CQRS/ES in a nutshell
  37. 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. 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. 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/

×