Multiple Write Models (suited and optimized for set of related commands)?

128 views
Skip to first unread message

hothi...@googlemail.com

unread,
Aug 18, 2016, 11:15:31 AM8/18/16
to DDD/CQRS
The title says it. Is there any reason that we limit us to one write model?
Why not have multiple write models, that are updated like the read models from the events with projections?
The Write models could be optimized for their commands and contain only the data that is needed in a form that is best suited for this command(s).
Taken to the extreme, each Command/CommandHandler could have it's own optimized Write Model.

Yes. The write models should be updated in one transaction, or you need some other version checking mechanisms that ensure your command does not act on stale data, but this should be no great challenge.
One could even ask if a command could not be handled by multiple command Handlers with different write models (doing different aspects of this command). If all changes are in one transaction we could implement it as an all or nothing regarding successfullness. This would be similiar to domain events that trigger changes in different bounded context (but on a smaller scale) or sagas/process managers (but with independent parallel steps).

I'm sure I'm not the first one who comes up with this idea, but I can find nothing about it.

So please enlight me why this is a stupid idea and why it is not used. :-)

Mark Murfin

unread,
Aug 21, 2016, 8:12:01 AM8/21/16
to DDD/CQRS
If you are finding value in writing multiple models but don't feel like you are duplicating business logic then I think you are just discovering different aggregates, without realizing it.

hothi...@googlemail.com

unread,
Aug 29, 2016, 6:33:54 AM8/29/16
to DDD/CQRS
Interesting hint. But I think what I mean is different.

Let me explain a simple (and really silly) example:

Let us assume we have some aggregate which holds a list of items (Like shopping cart or similiar).
Let us assume we have two commands.
The first lets us add an item and the business constraints to check are that the item is not already added. To implement this, we could just use a HashSet of the item keys to check wether the item was already added.
The second lets us remove an item. The business constraints to check are that only the last item can be removed (yes, I know that the command should be named "removeLast" in this case). To implement this we need an ordered list of the items to check if the one we should remove is the last. Later we decide that only the last added can be removed ever. Then we don't need the list, but only to remember the last added to check.

Of cource we could implement both commands in our aggregate and hold both the Hashset and the List (or the last added) in it, or go only with the list in both commands (complicating the implementation of the add check).
My idea now is, to have separate classes to implement this two commands and its constraints and each of them has its own optimized data structure that is best suited for their implementation. And both are hydrated from the same events (like 2 projections) handle a command and fire events (eg. ItemAdded, ItemRemoved).
This could also decouple and focus the implementation of very complex operations a bit.

What are the reasons (I think there are) not to do this?

urbanhusky

unread,
Aug 29, 2016, 7:37:07 AM8/29/16
to DDD/CQRS
 Wouldn't that run the risk of inconsistencies? Your aggregates serve as consistency boundaries. You could use strategies to separate the logic though.

Mark Murfin

unread,
Aug 31, 2016, 8:40:40 PM8/31/16
to DDD/CQRS
Consistency boundaries aren't necessarily class boundaries, so you can have two different classes taht represent the same aggregate. However, you have to be sure that the remove side is consistent with the add side. There will be a period of time where adds are still being processed by the remove side but has already been processed by the add side (because you chose data structures oriented for their performance in those two areas). So during that period of time, nothing can be removed. If you find that it is ok for things to be removed during that period of time, then you've discovered that your domain is ok with eventual consistency and you can break those two things into separate aggregates/boundaries/services (your choice of terminology).
Reply all
Reply to author
Forward
0 new messages