Jun 20, 2015
Idiomatic Domain Driven Design: implementing CQRS
Andrea SaltarelloCEO @ managed/designs
http://twitter.com/andysal74
http://slideshare.net/andysal
Who I am
1. CEO @ Managed Designs, striving to discover the perfect «sustainable software development process»
• Customer has to be satisfied and pay
• Supplier has to have a reasonable markup
• Team members should be satisfied with their work
2. Founder and leader of UGIdotNET (first Italian .NET User Group): I need to share experiences peer to peer
3. (Co)Author (together with Dino) of .NET: Architecting Applications for the Enterprise, by Microsoft Press
4. Basically, a software developer
What’s DDD?
Domain Driven Design:
• Is not a methodology
• Is not an architecture
• Is not a silver bullet
• Is an approach aimed to tackle the complexity of software development; its main assets are:
–Bounded Context
–Ubiquitous Language
–Aggregates
– (Events)
Ubiquitous Language
It’s the language spoken by all the people thatwork on a project; the UL spans from the documentation to the source code.
Basically, technicians should adopt the languagespoken by the business in order to reduce friction
Bounded Context
A Bounded Context is a bounduary whithin which a specific ubiquitous language applies
A system is a composition (Map) of (bounded) contexts(e.g.: web store, accountability, delivery&shipment …), speaking one to each other by means of some kind of API.
Due to the decoupling of contexts, we can use an ad hoc architecture for every context
Aggregates
Aggregates are atomic clusters of “objects” that existand interact inside a specific BC: every Aggregate actsas the “(both) data and behaviour” composition of an important concept which exists within the BC itself.
• Basically, a “DDD oriented” system does coordinate the work of aggregates
• The whole set of aggregates existing within a specificBC is the BC’s Domain Model.
• Should a specific behaviour exceed an Aggregate’sbonduary, it will be implemented as a (Domain) Service
• Model + Services == (Domain) Layer
Andrea vs. DDD, A.D. 2004
Got it: a system is a composition Map of Bounded Contexts, each one sporting a Domain Layer created after an Ubiquitous Language.
Awesome! Super Cool! Now… How the hell can we translate this in code?
2004: a Domain (Model) Odissey
DEMO
Domain Model (Voucher, NSK)
Is Domain Model broken?
Domain Model is (almost) ok, but to follow the “Blue Book style” is pretty hard and requires a lot of tradeoffs: is there a different way to havethe same approach applied?
DDD has two distinct parts. You always need one and can
sometimes happily ignore the other.
Analytical
Strategic
Valuable to everybody and every project
Blue book’s Domain Model is just one “supporting architecture”, though the one being originally recommended
Command Query Responsibility Segregation
A single model cannot be appropriate for reporting, searching and transactional
behaviours
[Greg Young]
CQRS at a glance
Query Command
CQRS in a nutshell
«Doing CQRS» means separating the stack that readsdata (query) from the one that can alter the system’sstate (command), each one having its own ad hoc«model»
All the actions that the system is capable of are expressed as Commands. To sum it up:
1. A user An actor ask the system to execute a command
2. Command execution alters the system’s state
3. The read model is used in order to query for (updated) data
What’s a «MODEL», anyway?
We’re not trying to have a model whichfaithfully represents the world, but one thatworks within a bounded context
.Net DeveloperDays 2014
Mercator projection (1569)
.Net DeveloperDays 2014
That’s the world map we’re used to and… It’s wrong, but itactually works (from a certain point of view)
Galls-Peters projection (1885 ⊕ 1973)
.Net DeveloperDays 2014
The Query side of the Force
The «Read Model» can be served in different flavours, such as:
• Plain SQL
• (Micro) O/RM
• Services (xml, json, DTOs, …)
• LET (Layered Expression Trees)
Layered Expression Trees (LET idiom)
As a business unit manager, I want to collect credits due to unpaid outgoing invoices #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)));
DEMO
Layered Expression Trees
The Command side of the Force
Sorry, non silver bullet available for implementingcommands, too. Common choices:
• Transaction Script
• Event Sourcing (we will talk about this tomorrow)
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.
Commands are «modeled» as functions, each onerepresenting one action that the system is capable of
DEMO
Transaction Script feat. CQRS
Next stop: Events. See you tomorrow
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]
Bibliography
[DDD] Domain Driven Design, Eric Evans , Addison-Wesley
[NAAE] Microsoft .NET: Architecting Applications for the Enterprise (2° ed.), Andrea Saltarello & Dino Esposito, Microsoft Press
[MERP] Merp, https://naa4e.codeplex.com/