I can only refactor so much, but i still need to create 2 domain object for Promotion (for example). One for command (which contains more accurate representation of Promotion from transaction/business view), and another one for query (Promotion as seen on UI/presentation by users).
In many cases, they are the same. I can write in Promotion object domain on Command side to define how the a particular promotion works on customer's bill.
When this promotion gets passed through messaging, I will end up doing the same logic in Query side of Promotion domain (to make sure promotion is applied appropriately to CustomerBillSummary report, and SubscriptionBillSummary report, BillDetail report, etc).
I can extract out this logic leaving domains of both bounded-contexts pretty anemic... if possible at all. The fact that the promotion works on totally different domain (between transaction-domain and report domain) makes it extremely hard to avoid duplication.
How does everyone overcome this problem?
Is CQS only intended for applications where auditting is heavily crucial (e.g. finance/accounting)?
And in "conventional" (non CQS) DDD application, how do you deal with screen-specific lists (while avoiding data-access problem)? Do you expose application-service and even repositories to presentation DTOs?
On Fri, Jul 3, 2009 at 11:37 PM, Carfield Yim <carfield@...> wrote:
Sorry to jump in to the discussion.... in fact I am not exactly sure if I understand your question totally.... but if you find that are duplication of logic, isn't you can always extract to a common method and reuse in difference place?
On Fri, Jul 3, 2009 at 9:34 PM, Hendry Luk <hendrymail@...> wrote:
Not sure what I was trying to say there :P
That should read:
My problem is: while in some particular cases, domains for query and command are different, but in most cases they are very similar.On Fri, Jul 3, 2009 at 11:29 PM, Hendry Luk <hendrymail@...> wrote:My biggest problem with CQS at the moment, is that processing Command inevitably involves queries.
From my understanding, however, command context doesn't normally communicate with query context. Instead, it reconstructs the entity from historical commands.
My problem is, while in particulary area of the applications domains for query and command are different, but they're mostly similar.
I.e., in most applications, the business domain during write is very similar with business domain of read. Nevertheless, in CQS we have to rewrite the same logic twice: one in each context (command and query).
For example, applying promotional discount to an order. This logic will have to live in command, so we could apply the promotion to domain entities using specific business logic.
In the other end of the communication, the same command gets fed as an event-message to the other context. The other context will apply same business logic, but in completely different view of the same elephant. It mostly deals with updating various 'query-specific' datastore, and knows nothing about domain-entity.
So in this case, the same logic has to be rewritten in both command side and query side.
And to make it even more complicated, the query-specific datastore is deliberately unnormalized. E.g., if you have different view for order per customer, and order per account, we make redundant maintenance, which is fine. However, when we introduce new concept like promotion, developers need to remember to maintain both viewpoints of that order. I think unnormalization for reporting-friendly purpose causes maintenance trouble, but can be justified for many reporting purposes (as in "reporting"), but i think would be maintenance nightmare if applied liberally for all queries in the application.
I know I'm still missing a lot of pieces in CQS. But it's difficult for me to overcome this issue without any implementation out there that I can use as reference (is there any?).
CheersOn Fri, Jul 3, 2009 at 11:04 PM, Greg Young <gregoryyoung1@...> wrote:
What duplication? It is the same amount of code just put into different places.
Also it does not *have* to be against 2 different data sources ....
using 2 data sources does add a lot of complexity due to eventual
consistency ... If you use just 1 data source then things are
relatively straight forward.
Greg--
On Fri, Jul 3, 2009 at 7:28 AM, Hendry Luk<hendrymail@...> wrote:
>
>
> Hi guys,
>
> I'm wondering what's your take about where presentation models get dealt
> with? E.g. screens where we do complex search/filtering then display the
> result in a very pedantic list of screen-specific representation.
> Ideally, presentation models are established in presentation-layer, whereas
> application-services and repositories produce the domain entities required
> to constitute the presentation. However, there are data-access implications,
> e.g. lazy-load.
> Hiding stuffs behind application-service, repository etc makes it difficult
> to make screen-specific projection (from ORM into DTO) to avoid N+1
> lazy-loading. E.g., a screen to search customers, which was initially nice
> and easy until the client ask a change request to add a column to the
> search-result list: "number of subscriptions the customer has".
>
> It's so tempting to let applicaiton-service (or repository) to deal directly
> with screen-specific DTO. But application layer is not supposed to deal with
> DTO or presentation-models. Many purists have always preached the importance
> of having mappers to translate DTO to application-layer, and that
> application-layer should only deal with domain objects. I just can't figure
> out how to maintain data-access optimization this way.
>
> OK, I'm aware of philosophy like CQS that separates query into different
> bounded context and data-store from usual domain entities. But I haven't
> bought into this yet. The upkeep cost for logic duplication is IMO enormous,
> and I can't justify yet to move to that architecture until I know better
> about it (which would be for another post).
>
> Cheers
> Hendry
>
>
Les erreurs de grammaire et de syntaxe ont été incluses pour m'assurer
de votre attention