My take on what CQRS is — and what it isn’t
Update: Rob Ashton put it way more eloquently than I ever could: CQRS is too complicated
Note: In his blog SOA Bits and Ramblings Jørn Wildt went through a couple of points concerning CQRS as being confused with a broad collection of (sometimes) complementary patterns.
My comment on his post became pretty long and I decided to cross-post it here as well. Since this is a comment, it contains references to the original post. So I recommend reading it first.
It’s good to see that not everybody is jumping the hype without thinking about it first.
As far as I can tell, you are not very far off the truth, but I wanted to quickly help clarify things.
First and foremost: CQRS as an architectural pattern has nothing to do with event sourcing, eventual consistency, messaging, pub/sub, denormalized views and whatever other patterns are being confused with the term CQRS nowadays. CQRS is simply having two separate models for each reads and writes, that are being accessed via queries and commands respectively. So basically what you say in 2) is pretty much what CQRS is all about.
As you described in 2), 3) and 4) you don’t need all the fuzz. Just use common sense and apply complementary patterns like view denormalization or event sourcing as needed. That’s what CQRS is all about: Simplification by viewing Read and Write as separate concerns.
Concerning collaboration: It’s not about concurrent access of the same type, it’s about modelling the domain. Different roles might modify the same aggregate with different intentions at different points in time/the aggregate’s lifecycle.
Whenever different people or different roles have use cases concerning a common aggregate, it might be considered collaborative imho.
So when do we apply DDD/CQRS?
Whenever a bounded context has a really complex model underneath AND it has a significant impact on our application’s value. The blue book calls it the “core domain”. i.e. don’t use CQRS on the accounting context, since this is pretty much a solved problem. (Except when you’re creating that new accounting app and thus it’s your core domain, of course.)
When do we apply Event Sourcing?
Most teams probably shouldn’t at all. Persisting state in a relational db and feeding your events into an event log pretty much gives you all you need:
The state-based db keeps being your single (and well-known) source of truth. And if you need to go back in time or project some new views or reports off historical data, go through your event log and take what you need. But even an event log is an addition to, not core part of CQRS.
When do we denormalize our views into a separate datastore?
We already do most of the time. It’s called caching. It helps with performance issues and scalability. But as you correctly stated, it’s not needed until it’s needed. And it’s yet another pattern being confused with CQRS.
The same goes for messaging, integration patterns, etc.
Long story short: The difficult part is not (and shouldn’t be) the infrastructure. The difficult part is modelling your domain. Focus on that and use CQRS in whatever bounded context it may help reduce to complexity of trying to stuff reads and writes into one big model.
Everything else I’d consider premature optimization.