Life would be simpler if it were "more often than not" but e-commerce
discount mechanisms often include context-dependent rules like "if
they've got any kind of camera and they've got a battery and they've
got the voucher code BATTERY50, then discount the battery by 50%".
This is "calculating" as opposed to "querying" and can't be done by
filtering on a prepared-in-advance read model. There are quite a few
similar scenarios to this like calculating shipping costs based on
weight / volume / product type rules.
One solution would be to isolate discount calculation within a
separate Discounts bounded context containing Discount domain objects
that can be set up with rules and discount logic. This functionality
would then be exposed via a simple API, e.g.
DiscountService.CalculateDiscounts(Basket basket). This would use the
Discount objects to calculate any discounts that could be applied and
return an object containing the results of the calculation.
We're going to have the usual issues with lazy-loading and pre-fetch
paths when we load the Discount objects to do the calculation though,
so we could look at how applying CQRS within the Discounts BC might
help us. One approach:
- The Discount domain objects contain functionality for adding /
editing rules and discounts and for validating state. However they
don't know how to actually calculate discounts - they're more like a
"schema" for the discount
- A separate "calculation-optimised" read model (e.g. C# object graph)
contains logic used to perform the calculation according to the
discount "schemas". This is kept in sync with edits to Discount domain
objects, the entire object-graph is serialized as XML / json and is
stored in a cache.
- The DiscountService retrieves the "calculation-optimised" read model
from a cache and gets on with its business without ever hitting a
database. It's really fast.
The read-model-with-behaviour idea is interesting, as most CQRS
example scenarios involve generating static behaviour-free data in
read-models for display in the view. There seem to be plenty of other
applications!
Dan