35
Layered Expression Trees feat. CQRS 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/

Layered Expression Trees feat. CQRS

Embed Size (px)

DESCRIPTION

CQRS, ovvero: 2 stack, uno per "leggere" e l'altro per "scrivere". Se per "scrivere" abbiamo l'imbarazzo della scelta (Domain Model, Command, Event Sourcing, ...) per leggere, invece, apparentemente c'è poco da dire. "Apparentemente", appunto. Parliamone :-)

Citation preview

Page 1: Layered Expression Trees feat. CQRS

Layered Expression Trees feat. CQRS

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/

Page 2: Layered Expression Trees feat. CQRS

Andrea Saltarello! Chi era costui?

• C.T.O. di Managed Designs, alla ricerca della «sostenibilità dello sviluppo software» 1. Il cliente «deve» essere soddisfatto e pagare 2. Il fornitore «deve» avere un margine ragionevole 3. Il team «deve» essere soddisfatto del proprio lavoro

• (Co)Fondatore e presidente di UGIdotNET: ho bisogno di condividere esperienze a causa del bullet precedente

• (Co)Fondatore e collo di bottiglia di GUISA • (Co)Autore di .NET: Architecting Applications

for the Enterprise di Microsoft Press • Il #NAAE è il mio giornale di bordo, nel quale (nel

2008) ho cercato di «sintetizzare» i punti 1 e 2

Page 3: Layered Expression Trees feat. CQRS

In realtà…

Andrea Saltarello è l’amico di penna di @ayende

Page 4: Layered Expression Trees feat. CQRS

«BLUE» DDD

Page 5: Layered Expression Trees feat. CQRS

Blue Book: Architettura (1/2)

Page 6: Layered Expression Trees feat. CQRS

Blue Book: Architettura (2/2)

è 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

Page 7: Layered Expression Trees feat. CQRS

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

Page 8: Layered Expression Trees feat. CQRS

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.

Page 9: Layered Expression Trees feat. CQRS

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à.

Page 10: Layered Expression Trees feat. CQRS

CQRS

Page 11: Layered Expression Trees feat. 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/ ]

Page 12: Layered Expression Trees feat. CQRS

Command Query Responsibility Segregation

Query Command

Page 13: Layered Expression Trees feat. CQRS

CQRS, a.k.a. «Stato di Diritto»

CQRS introduce in DDD la «separazione dei poteri»

• 1 stack per «leggere»

• 1 stack per «eseguire»

In pratica, significa non dover «indovinare» un modello valido per entrambe le esigenze

In questa sessione ci interessa la «Q»

Page 14: Layered Expression Trees feat. CQRS

Scenario 1: e-commerce

Home page: visualizzare prodotti raccomandati

Considerati tutti i prodotti catalogati, dall’elenco di quelli in vendita presentare i 3 aventi maggior giacenza in magazzino.

Ergo:

• Prodotti catalogati->Prodotti in vendita (domain)

• Prodotti in vendita->3 prodotti aventi maggior giacenza (application)

Page 15: Layered Expression Trees feat. CQRS

Scenario 2: ERP

Visualizzare fatture insolute di una business unit

Considerate tutte le fatture, estrarre quelle attinenti una business unit e tra esse visualizzare tutte quelle scadute e non pagate a distanza di 30 gg dalla scadenza

Ergo:

• Fatture emesse -> Fatture della BU

• Fatture BU -> Fatture scadute

• Fatture scadute -> Fatture insolute

Page 16: Layered Expression Trees feat. CQRS

Scenario 3: CMS

Visualizzare gli ultimi 5 articoli

Considerati tutti gli articoli, dall’elenco di quelli pubblicati estrarre i 5 più recenti

Ergo:

• Articoli -> Articoli pubblicati

• Articoli pubblicati -> 5 articoli più recenti

Page 17: Layered Expression Trees feat. CQRS

Scenario 4: CMS (Reloaded)

Ricerca articolo

Considerati tutti gli articoli, dall’elenco di quelli pubblicati estrarre quelli che soddisfano i criteri di ricerca

Ergo:

• Articoli -> Articoli pubblicati

• Articoli pubblicati -> articoli che soddisfano la query

Page 18: Layered Expression Trees feat. CQRS

Scenario 5: e-commerce (strikes back)

Ricerca prodotti

Considerati tutti i prodotti catalogati, dall’elenco di quelli in vendita estrarre quelli che soddisfano i criteri di ricerca.

Ergo:

• Prodotti catalogati->Prodotti in vendita

• Prodotti in vendita-> prodotti che soddisfano la query

Page 19: Layered Expression Trees feat. CQRS

La «Q» in CQRS

Cosa hanno in comune questi casi?

• Ogni «filtro» è una regola che «lavora» sul grafo

• Composizione di regole

• Ogni regola può essere usata in differenti parti dell’applicazione

Come fare… Senza un «botto» di DTO?

P.S.: Si, «botto» è un ordine di grandezza del S.I. Kilo->Mega->Giga->Tera->Peta->Botto

Page 20: Layered Expression Trees feat. CQRS

Layered Expression Trees (LET idiom)

Facciamo un gioco: facciamo che layer e servizi si scambino degli IQueryable<YourFavouriteDomainEntity> facendo «emergere» la query e specificando la proiezione solo all’ultimo momento?

Page 21: Layered Expression Trees feat. CQRS

LET idiom feat. Ubiquitous Language

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

Page 22: Layered Expression Trees feat. CQRS

Query Command

LET feat. CQRS

Page 23: Layered Expression Trees feat. CQRS
Page 24: Layered Expression Trees feat. CQRS
Page 25: Layered Expression Trees feat. CQRS

The Good

Ridotto effort di realizzazione/gestione: • Nessun DTO (ad eccezione del ViewModel,

che avremmo comunque) • Modello «database like» facile da ottenere

rapidamente • Strutturazione «DDD like» della logica

• Se il DBMS è SQL Server, funziona «out of the box»

Performance: • Estrazione «all at once» di tutti e soli i dati

necessari

Page 26: Layered Expression Trees feat. CQRS
Page 27: Layered Expression Trees feat. CQRS

The Bad

Unit testing «acrobatico»:

• In pratica, LINQ 2 Objects (o similari)

• In ogni caso, è un LINQ provider differente :-/ #meh

Page 28: Layered Expression Trees feat. CQRS
Page 29: Layered Expression Trees feat. CQRS

The Ugly

• NHibernate è praticamente inutilizzabile: il LINQ provider «scoppia»

• Ogni LINQ provider è una storia a sè

Page 30: Layered Expression Trees feat. CQRS

One more thing… (cit.)

Page 31: Layered Expression Trees feat. CQRS

LET idiom, v2

Se:

• dovessimo realizzare una applicazione e non un framework

• per noi gli idiomi fossero «belli belli belli in modo assurdo» (cit.)

…Allora potremmo rimpiazzare i servizi con degli extension methods ad hoc

Page 32: Layered Expression Trees feat. CQRS

LET idiom, v2

public static class OutboundInvoiceExtensions { public static IQueryable<OutboundInvoice> RetrieveExpiredOutboundInvoices(this IQueryable<OutboundInvoice> query) { var expiredInvoices = from i in query.RetrieveUnpaidOutboundInvoices() where i.PaymentDueDate < DateTime.Now select i; return expiredInvoices; } public static IQueryable<OutboundInvoice> RetrieveUnpaidOutboundInvoices(this IQueryable<OutboundInvoice> query) { var unpaidInvoices = from i in query where i.Status == "E" select i; return unpaidInvoices; } public static IQueryable<OutboundInvoice> FilterByBusinessUnit(this IQueryable<OutboundInvoice> query, int businessUnitId) { var invoices = from i in query where i.JobOrder.BusinessUnit.OrganizationID == businessUnitId select i; return invoices; } }

Page 33: Layered Expression Trees feat. CQRS

LET2 feat. Fluent Ubiquitous Language

Sembra Specification ma non è, serve a darti l’allegria! (semi cit.)

expiredOutboundInvoices = from i in

ReadModelFacade.OutboundInvoices .FilterByBusinessUnit(businessUnitId)

.RetrieveExpiredOutboundInvoices()

orderby i.PaymentDueDate

select new

SummaryViewModel.OutboundInvoice

{

Id = i.ID,

CustomerName = i.Customer.Name,

PaymentDueDate = i.PaymentDueDate.Value,

TotalAmount = i.TotalPrice,

JobOrderName = i.JobOrder.Name,

Code = i.Code

};

Page 34: Layered Expression Trees feat. CQRS

PARLIAMONE

Page 35: Layered Expression Trees feat. CQRS

Bibliografia “pratica”

[DDD] Domain Driven Design, Eric Evans , Addison-Wesley

[NAAE] Microsoft .NET: Architecting Applications for the Enterprise, Andrea Saltarello & Dino Esposito, Microsoft Press

CQRS, Task Based UIs, Event Sourcing agh!, Greg Young

[NSK] NSK, http://nsk.codeplex.com

Mio blog ENG, http://blogs.ugidotnet.org/mrbrightside