Where should “derivation” logic go?

307 views
Skip to first unread message

marko

unread,
Aug 5, 2012, 12:22:23 PM8/5/12
to ddd...@googlegroups.com

When there is “derived data” in a view/projection/query, there should the derivation logic reside?

Martin’s discussion of “Eager Read Derivation” suggests that the “domain model” runs the derivation logic.  But the example does not use separate Command/Query models. 

http://martinfowler.com/bliki/EagerReadDerivation.html

In the context of CQRS, where should the derivation domain logic go?  I’m assuming in most cases it should be located on the Query side, but I would like to confirm that?  Would it also be standard practice for the Query model to publish Events for derived results (in Martin's example - BecamePaternalGrandfatherEvent)?

Thank you.

Greg Young

unread,
Aug 5, 2012, 12:52:18 PM8/5/12
to ddd...@googlegroups.com
Projections generally live outside the domain model. If however you are event sourcing your domain objects *they are a projection*. 

As for projections that emit events I generally consider these special, they can either be implemented like regular projections (though a bit odd as do you replay them? They potentially have side effects). They can also be very complex leading to a domain model that is a downstream event processor (consider algorithmic trading).

Hth

Greg


--
Le doute n'est pas une condition agréable, mais la certitude est absurde.

marko

unread,
Aug 5, 2012, 2:32:46 PM8/5/12
to ddd...@googlegroups.com

Thanks Greg.

 

>> Projections generally live outside the domain model.

 

That statement also brings up a side-bar question –

…for a CQRS/EventSourced system, what is the Domain Model? 

My understanding is that Command Model + Query Model(s) == the Domain Model?

 

Returning to the original question, so for a CQRS/EventSourced system, are you saying that Martin’s suggestion (and yours?) is that derivation logic should reside in the Command Model?  In that case the calculation/derivation of PaternalGrandfather would be a result of Command processing and published as an Event to Projections?

 

What about when PaternalGrandfather is not a concern of the Command Model and is never used by it for maintaining invariants or for any other reason (except to publish it)?  And for my system’s particular case we would have many projections with values that are not required by the Command Model.  I would be concerned that the Command Model would be polluted with a lot of Query logic noise that is not essential to it (which seemed to be central to purpose of factoring out the Query Model)?

 

If the Query Model is considered the portion of the Domain Model concerned with Queries, then it would seem that query derivation logic would find a natural home there?

>> (though a bit odd as do you replay them? They potentially have side effects)

Wouldn’t you treat this case as you would with the Command Model – replaying events for the Command Model does not republish any Events?

Thank you.

marko

unread,
Aug 7, 2012, 11:30:47 AM8/7/12
to ddd...@googlegroups.com
Some more thoughts.

  • If a derivation logic is not significant to the Command Model, then do not put it there.
  • Normally a Query Model simply denormalizes subscribed Events.  ie. there is no significant logic - just persisting related Event data.  In these cases where there is no Query Model business logic, we can think of the View as being a simple data "Projection".
  • If the View has significant derivation logic, then maybe it is more appropriate to think of the View as a first-class Bounded Context, with it's own domain logic?  Maybe in this case it's more appropriate to call the View Bounded Context a "Query Model" (rather than a data Projection)?  The Query Model subscribed-to Events are similar to Commands, in that they trigger business logic (derivation logic), which emits one-or-more state change Events (just as with a conventional Command Model).  The Query Model is notified of it's own Events, where the state change is physically applied (just as with Command Models).  Other Bounded Contexts can subscribe to the Query Model's Events.

belitre

unread,
Aug 8, 2012, 8:41:23 AM8/8/12
to ddd...@googlegroups.com


El domingo, 5 de agosto de 2012 20:32:46 UTC+2, marko escribió:

Thanks Greg.

 

>> Projections generally live outside the domain model.

 

That statement also brings up a side-bar question –

…for a CQRS/EventSourced system, what is the Domain Model? 

My understanding is that Command Model + Query Model(s) == the Domain Model?

 

 
I think that "Command Model == Domain Model" when the read model just holds projections for UI purposes. No behaviour in read model, just a flat view of your domain model.
But there is not a strict rule. If the business deals with complex projections / calculations then your read model could be part of your domain. 
 

Returning to the original question, so for a CQRS/EventSourced system, are you saying that Martin’s suggestion (and yours?) is that derivation logic should reside in the Command Model?  In that case the calculation/derivation of PaternalGrandfather would be a result of Command processing and published as an Event to Projections?

 

What about when PaternalGrandfather is not a concern of the Command Model and is never used by it for maintaining invariants or for any other reason (except to publish it)?  And for my system’s particular case we would have many projections with values that are not required by the Command Model.  I would be concerned that the Command Model would be polluted with a lot of Query logic noise that is not essential to it (which seemed to be central to purpose of factoring out the Query Model)?

 


I think that generate new meaningful domain knowledge (facts, events) is a good reason for something to belong to the Command Model. But it would be better to discuss this with concrete examples.
Can you explain your domain without those events?

marko

unread,
Aug 8, 2012, 8:00:59 PM8/8/12
to ddd...@googlegroups.com
Thanks @belitre

I agree with your statement that complex projections (containing logic) could be part of the domain.

>> I think that generate new meaningful domain knowledge (facts, events) is a good reason for something to belong to the Command Model.
>> But it would be better to discuss this with concrete examples.  Can you explain your domain without those events?

No real-world examples at this time.  I am just getting up to speed and trying to understand things better.

But a concrete exampled that inspired the question is Fowler's EagerReadDerivation pattern wiki page.

The PaternalGrandfather sounds like it is part of the Ubiquitous Language of the domain, but it does not appear to be essential to the Command Model.  In this case it was needed for a View.

I agree it could be emitted by the Command Model, particularly if it's a core concept of the domain.  But i'm not sure the Command Model should be required to generate Events because a particular View requires it.  It feels like the Command Model should generate the Event if there is a good reason - in the context of the Command Model.  But if it turns out that there is a never ending list of ReadDerivation Events being added to the Command Model, only because Views require them, then it seems like there is forced coupling going on and confused responsibilities?  And if the Query Model is a first-class part of the Domain, then why not put the Query logic there, rather than pollute the Command Model with Events that are not essential to it?  Seems like the Query Model should be responsible for Query logic?

Thanks again.

belitre

unread,
Aug 9, 2012, 3:04:03 PM8/9/12
to ddd...@googlegroups.com


But i'm not sure the Command Model should be required to generate Events because a particular View requires it.  It feels like the Command Model should generate the Event if there is a good reason - in the context of the Command Model.  But if it turns out that there is a never ending list of ReadDerivation Events being added to the Command Model, only because Views require them, then it seems like there is forced coupling going on and confused responsibilities?  And if the Query Model is a first-class part of the Domain, then why not put the Query logic there, rather than pollute the Command Model with Events that are not essential to it?  Seems like the Query Model should be responsible for Query logic?

Well, again, there is not definitive answer here without adequate context... but I don't understand your concern. Your views are different ways to see / read your model. The important think is that your don't generate knowledge out of the domain. If you pre-process or process the views per request is just a matter of performance.

In cases where new knowledge can be infered as a read model (think of a store of rdf triples which can be queried with different ontologies matching), I would consider those ontologies as part of the domain model.

Perhaps If we rename Query Model to UI Read Model, we won't have discussion. You could have other read models belonging to the domain that are not generated for presentation purposes.

Everything changes if we talk about "generating Events because of Integration needs". We have some ugly modeling here, but I will start another post for that.

marko

unread,
Aug 9, 2012, 5:46:07 PM8/9/12
to ddd...@googlegroups.com
Hi @belitre.

I'm not sure why we can not use the example given by Fowler as adequate context?  

My question is whether the calculation of PaternalGrandfather should be done in the Command Model or Query Model (assuming they are physically separate models, and assuming PaternalGrandfather is not used by the Command Model)?  I have seen it suggested several times that the logic should be calculated in the Command Model and published as an Event so that the Query Model is restricted to being a simple read Projection.  

But my concern is that question of PaternalGrandfather does not look to be the responsibility of the Command Model in this case (it looks like a Query, not a Command)?  Similar to the issues in your recent post about Integration Events, in this case the Command Model would likely not even know that it should generate PaternalGrandfather since it's not used by the Command Model.  It would more likely be driven by the team that is creating the new Query Model to support the new UI.  That UI would require PaternalGrandfather for display, and again my concern would be if the UI/*Query* requirement drove the an enhancement of the Command Model to generate an event to publish the PaternalGrandfather answer.  

If you say that it is fine to put the PaternalGrandfather logic in the Query Model, then i'm good (and i have misinterpreted guidance on the topic).

Thanks.

belitre

unread,
Aug 10, 2012, 2:45:35 AM8/10/12
to ddd...@googlegroups.com


If you say that it is fine to put the PaternalGrandfather logic in the Query Model, then i'm good (and i have misinterpreted guidance on the topic).


No, I don't say that.
I'm generally comfortable with the idea that we have to think in consumers of information when deciding what knowledge our domain generates. I want to have PaternalGranfather logic in the command model. A projection for UI purposes doesn't produce new concepts. Anyway I'm not an authority in this area so take this with distrust... :-)
Reply all
Reply to author
Forward
0 new messages