I am putting together a presentation for a lunch-and-learn for my local team on CQRS.
Everything has tradeoffs and no presentation sits well if it seems to just be cheerleading for something. What would you say is CQRS' disadvantages? (And, by CQRS, I do mean the design pattern, and not event sourcing, DDD or other mixins people commonly use along with CQRS.)
So far, I have seen:
- Newness/unfamiliarity in most development ecosystems.
- Added complexity in the user interface. (It's harder to design an asynchronous interface.)
- If your CQRSing is more than just "logical", you may have added:
- complexity in the physical implementation due to an increase in technologies used.
- added potential of data inconsistency.
Anything wrong, or more?
On Monday, February 28, 2011, mynkow <myn...@gmail.com> wrote:
> True, but then you better go for a standard CRUD model.
> Your UI should do the validation for the objects and try to pass valid data with the command. After that sends the command and that is it. Do not wait the command to be completed and refresh from the read model, never. You should know that cqrs applies to 5-10% of the projects, so if you tell us more we can help you.
--
Les erreurs de grammaire et de syntaxe ont été incluses pour m'assurer
de votre attention
I disagree on your CRUD remark, but these are IMHO the major drawbacks
vs advantages:
- Explicit messages add a lot of protocol (LOC) <-> Making everything
explicit and decoupled makes refactoring a breeze
- It can be difficult to model AR's and saga's <-> CQRS forces you to
think about and fully understand your domain
- Eventual consistency is introduced<-> Eventual consistency is always
there, CQRS makes it more explicit and allows you to prioritize things
- Lasagna code <-> you have 3 distinct problem domains : business
domain, UI and viewmodel building => mythical man-month effect is
reduced & you can have different experts for each problem domain
- message bus vs direct invokes <-> possibility to postpone and/or
remote invocations, BDD tests are a breeeze
One point I see as a possible disadvantage (since this is something
that one can face) is: The "fear of change".
This applies when you want to sell CQRS(+ES) to the stakeholders since
is not the >>traditional<< 3-tier or layered architecture people are
used to. (You can add some other reasons too)
Yes, people like new things but want "something tried and save" to
mitigate risk, which is not always the way people / decision makers
view CQRS (Oooh... is this new?).
I disagree. That is one of its strengths but also one of its flaws.
Cheers,
Nuno
> From the reactions I've had following presentations is unanimously positive, atleast from developers.
> And I bet most of them are from an N-tier background.
That is because most developers don't really understand the domain. They know about architecture though.
In fact, in the big ball of mud of things CQRS has been applied over and over.
IMHO what makes interesting in Greg's and Udi's (where is he by the way, we miss him here) view of this stuff, they not only bring a domain driven design perspective to it (Intelligent domain objects and aggregates), but also adopt a pragmatic perspective to the task. Naming messages is IMHO between events and command is the least valuable assertion. We have been doing that for years, yet the mud seamed to be unavoidable in a lot of projects.
I should point out, that any data/fact integration task is by itself eventually consistent.
What we still lack, at least I do and have been thinking about it, is a complete practical modeling and design theory in designing business facts around domain events intertwined with concepts such as Entities and Aggregates has processing engines. On top of this, we also need to define the logical mechanisms that we can use to manage eventual consistency between fact replicas considering multiple time lines.
This considering events are ubiquitous artifacts in CQRS.
So if there are any drawbacks, I would say immaturity of the model based on my experience, yet a lot of practical lessons to learn and to apply in real life. We are still steps away to take the most of CQRS in our solutions without resorting to things that work but still leaves me with a taste of an hack.
Cheers,
Nuno
That is the first sign that there are problems :) We are still learning ... I think.
It is very difficult to measure the impact of business rule fragmentation (implement some in the UI, a bit the Entity another in the Aggregate and some other in a Saga). Usually means loosing business competitiveness, in the medium to long run.
This might not be a problems still, considering that most IT solutions are relatively short lived. Take a startup, in might flop in less then 3 years.
Cheers,
Nuno
>>> - It can be difficult to model AR's and saga's <-> CQRS forces you to
>>> think about and fully understand your domain
I disagree that it necessarily forces us to have a deeper insight of the domain. This can can be flaw and a strength in context. It is a Strength because its is versatile, but his also a weakness since it can lead us to a false sense for understanding.
ARs are design constructs. They are not difficult to model if we know about domain modeling and DDD.
I remember Udi posts and his strong emphasis on Bounded Contexts along with Sagas et all. Unfortunately he was reusing this term from DDD with his own mindset.
The concept of Bounded Context in DDD is mostly driven by managing complexity of ones solution. It does not give a baseline to discuss what his was is not part of a bounded context.
For instance, he considered a Shopping Cart defining a Bounded Context and Order as defining another BC in itself as far as I remember. He did this almost intuitively as most experienced modelers do.
Bounded Context: http://domaindrivendesign.org/node/91
His variant was mostly concerned with the UL and in particular homonymous concepts and related challenges. Unfortunately this was lost in definitions.
The key term of Bounded Context, is Context. His context was the UL and he used this to establish greater insights on the way he designed a domain model. It is hard to establish what is a domain model or several in one single solution especially when we articulate multiple Bounded Contexts with one single broad activity, say a Sale.
Me and him have disagreed in some things, but not in most of the things as far as I remember. Unfortunately an online forum, tends to drag things that lack consensus, becoming more relevant rather then consensus.
Cheers,
Nuno
Sorry I'll try again, I understand that the interpretation could go both ways.
- It can be difficult to model AR's and saga's <-> CQRS forces you tothink about and fully understand your domain
I disagree that it necessarily forces us to have a deeper insight of the domain. This can can be flaw and a strength in context. It is a Strength because its is versatile, but his also a weakness since it can lead us to a false sense for understanding.
ARs are design constructs. They are not difficult to model if we know about domain modeling and DDD.
I remember Udi posts and his strong emphasis on Bounded Contexts along with Sagas et all. Unfortunately he was reusing this term from DDD with his own mindset.
The concept of Bounded Context in DDD is mostly driven by managing complexity of ones solution. It does not give a baseline to discuss what his was is not part of a bounded context.
For instance, he considered a Shopping Cart defining a Bounded Context and Order as defining another BC in itself as far as I remember. He did this almost intuitively as most experienced modelers do.
Bounded Context: http://domaindrivendesign.org/node/91
His variant was mostly concerned with the UL and in particular homonymous concepts and related challenges. Unfortunately this was lost in definitions.
The key term of Bounded Context, is Context. His context was the UL and he used this to establish greater insights on the way he designed a domain model. It is hard to establish what is a domain model or several in one single solution especially when we articulate multiple Bounded Contexts with one single broad activity, say a Sale.
Me and him have disagreed in some things, but not in most of the things as far as I remember. Unfortunately an online forum, tends to drag things that lack consensus, becoming more relevant rather then consensus.
Cheers,
Nuno
On Mar 1, 2011, at 11:13 AM, Tom Janssens wrote:- It can be difficult to model AR's and saga's <-> CQRS forces you tothink about and fully understand your domainI disagree. That is one of its strengths but also one of its flaws.Could you be a bit more elaborate on this; I do not quite get what youare stating here ?On 1 mrt, 11:44, Nuno Lopes <nbplo...@gmail.com> wrote:- It can be difficult to model AR's and saga's <-> CQRS forces you tothink about and fully understand your domainI disagree. That is one of its strengths but also one of its flaws.Cheers,Nuno
--
We could say that a story is usually within a BC but as you mention
below a steak can be had while traveling on a train, that does not
imply some direct relationship between them.
That was no my intent. My intent was to demonstrate that CQRS does not have any position regarding conceptual boundaries in terms of the UL. Wether we use Bounded Context, Use Cases, BDD Stories or artifacts to describe them. Its is not a CQRS facet neither it makes it explicit.
Something that is paramount to fully understand the domain.
I have not doupt what a Bounded Context is in DDD terms. Indeed I emphasized an old exchange of ideas we had in the DDD forum around the use of BCs by Udi. Which was not inline with DDD as it seamed back then.
Still the point he did was indeed important I think to CQRS, name it according to the preferred discipline.
Cheers,
Nuno
You can correct me of I'm wrong, I'm a BDD noob yet not from other similar practices.
The business boundaries of a BDD Story can be say one of a Sale. Yet the story can cross cut several BCs.
When we refine the story, adding more detail and eventually factoring it out into smaller stories we may end up with each of these smaller stories be within one BC. We might discover new BCs etc.
Still the initial story defines a process flow that encompass multiple BCs.
On another note we might have an initial equation of what our BCs are. Based on experience and by evaluating legacy systems, but others emerges from the complexity of the problem domain as defined in stories and some are actually eliminated.
All in all I'm trying to understand this phrase of yours that I don't agree with yet other experiences are totally valid :)
>>>>>>>>>> - It can be difficult to model AR's and saga's <-> CQRS forces you to
>>>>>>>>>> think about and fully understand your domain
I have a hard time imagining how the separation of views from the model, commands (present/future) from queries and domain events (past), together with a BUS (even if abstract) forces one to think about the domain in ways more simple domain modeling DDD. Maybe with an example would be easier.
I've seen people trying to model a Shopping Cart around the concept of Order, guess what it does not work well. It clutters ones code and reduces flexibility. The temptation is great because the items in a Shopping Cart are quite similar to OrderLines in an Order.
You can imagine that in these cases people are trying to model the Shopping Cart simply as a State of an Order (or flag).
Adding commands, queries, domain events and a BUS it does not help at all. In the end of the day we could still have ShoppingCartSubmitted (by simply changing the State of the Order object), OrderSubmitted and so on. The data in these events could even be extremely similar.
The important thing to realize is that the clockwork of a Shopping Cart is different then one of an Order even when they look similar. In other words, the context of its use is different. Hence they need to be distinct Aggregates.
Cheers,
Nuno
ok, this was pars pro toto; imho CQRS leverages proper DDD design
(think SOC again)
ok, this was pars pro toto; imho CQRS leverages proper DDD design
(think SOC again)Yes. CQRS is part of DDD. IMHO Talking about it without DDD mindset all we are talking is messages and pipes along with cache. Nothing new. MVC applied on a network scale.
What establishes a framework for reasoning about the domain into our designs is DDD.
If you want a buzz concept, CQRS + DDD = Domain Driven Messaging or Networking.
This is just my opinion.Cheers,
Nuno
Sent from my iPad
Hi Nuno,Wasn't DDD + CQRS + etc == DDDD (aka distributed DDD)?Rinat
.... if you use CQRS w/o DDD, but with ES ... - Klang
> Actually, using CQRS/DDD without ES and with domain events is what I'm currently doing in production (we're migrating from the DTO world).
http://martinfowler.com/eaaDev/DomainEvent.html
If you are using Greg's ES style. The Aggregate works as a simple event processor. Consuming external and self generated events (Greg's style) . It extends the EP by also generating events.
http://martinfowler.com/eaaDev/EventSourcing.html
Cheers,
Nuno
I have said that I can't envision Domain Events without some sort of ES. You have said that you use Domain Events without ES, I'm trying to understand how. The concept of ES and Domain Events overlap by definition.
I honestly thought you where using Event Backlogs, aka Event Stores.
Event Sourcing is not about persisting objects as a stream of events as you have written here: http://abdullin.com/journal/2010/11/16/key-cqrs-ingredient.html
We can discuss Udi's use of Domain Events though. I think that NServiceBus might make the backlog transparent by default while allowing the developer to configure the system so that events can be replayed from the backlog or even analyzed when needed. I like most of his way of materializing this in the framework.
Having said this Im not a fan of this article regarding the use of Domain Events: http://www.udidahan.com/2009/06/14/domain-events-salvation/
It seams to be describing a generic event handling mechanism similar to C#, yet instead of having observers over entities, we have observers of a registry of events to which he calls Domain Events.
I think that this is powerful, nevertheless don't see that the article makes such a good case for Domain Events.
Cheers,
Nuno
I re-read the code of Udi's article let retract.
The closest you can get to Domain Events with Udi article his class DomainEvents works has a in process event backlog (Event Log or Domain Log, it does not matter). Then he uses the Observer Pattern to notify Observers (handlers) of changes in state per type of Domain Event. Observers can be anything, including something like Handler Classes that can translate the event to another Aggregate. His Handlers work as EP (Event Processors)
The Observer Pattern is a variant of a more broad concept of Publish/Subscribe.
Ok, you may not be using ES currently.
> Event sourcing == persistence approach in which entity is persisted as a stream of events leading to it's current state.
That is not the industry definition of ES, currently. But I can see that is one view on the matter, valid has any.
> Domain event == event that has been dispatched by AR into the messaging infrastructure and is capable of crossing domain boundaries (if we directly publish our persistence events, they need to be enriched with AR info either within message body or within transport headers)
Check Erics Cargo sample. it's much more then that. Domain Events in DDD can be part of the domain model in his example and is not dependent on a publish/subscribe at all. In this case it is close to event sourcing and can be augmented up to Greg's approach.
I see more value in using Domain Events this way in terms of domain design rather then the above domain event dispatching mechanism based on publish/subscribe.
So yes, you may use Domain Events without ES, but in this case I don't see what the word Domain adds to the Event equation in CQRS. Checks Erics sample, it does add to the model (LOAD CARGO, UNLOAD CARGO, etc etc).
Cheers,
Nuno
> The difference between our terminology probably is showing up because in my distributed world, there is no "The Application", but rather a mesh of various components operating within different consistency boundaries, failure modes and data centers.
We also don't have the Application if not for a URL and what the users perceive to be. We are quite distributed and heterogenous. Having said this I see your point.
Cheers,
Nuno
As I travel around I often ask for a show of hands of how many people
process more than 10 transactions per second. I get very few, I can
process 10 transactions per second on my cell phone.
You are correct though in that the introduction of analysis is the
largest cost associated. Introducing analysis on a project that really
doesn't need it can be a recipe for disaster.
Greg
--
Well, I am looking specifically at CQRS. At subsequent lunch-and-
√iktor Klang wrote:
> I think ES in itself has more intrinsic value than just CQRS, so not using
> it if you have the opportunity is a shame really.
learns, I will cover the other concepts.
However, the asynchronous calls and how to handle them is definitely
> > Depends on your tooling, most times it can actually become simpler because you have a separation of the reader and the writer in the UI
not the norm, wouldn't you say?
> >
> > -
> > - If your CQRSing is more than just "logical", you may have added:
> > - complexity in the physical implementation due to an increase inRight. That's why I used an if...then.
> > technologies used.
> >
> > This is highly situational, you don't have to add any extra technologies if
> you don't want to.
> >
> > - added potential of data inconsistency.
> >Well, from the user's perspective, yes. But, from the system's
> > That's the entire thing with CQRS, data is always inconsistent
perspective, data must be consistent or "eventually consistent", as it
is often said.
However, by dividing the read and write sides, you
introduce a point of failure which can ruin consistency if you don't
plan for it... if necessary.
Thanks for your input.