在对事件源域模型进行建模时,具有“技术”事件可以吗?

时间:2019-01-30 21:06:17

标签: domain-driven-design cqrs event-sourcing

当前,我正在为我的一个项目建模基于事件源的域逻辑。

它基于 CQRS ,具有非规范化的sql读取端,而写入端则具有事件流。

我有一个要求,一个域的实体应具有某种status属性(基本上是一个枚举)。 status可以通过两种方式进行更改:由系统用户直接更改或由于系统中其他更改而更改。从域的角度来看,只有用户的更改是 true 更改,因此对于自己的事件应得到,可以从当前状态(其他属性)计算其他状态转换。

但是。 status属性在读取模型中至关重要。此外,系统应提供当前实体status和所有历史状态。但是,为了做到这一点,我似乎需要针对所有状态转换的技术事件,系统会在计算出的状态真正发生变化后发出该事件。

从理论上讲,我可以避免发生那些技术事件。我考虑此选项的唯一原因是因为实体的更改日志,现在它是相关事件的简单漂亮打印。

2 个答案:

答案 0 :(得分:1)

简短的回答:事件来源警察不会追随您。

更长的答案:在短期内,将计算的值存储在事件中还是只写先行数据,然后让读取的模型自己运行计算,就无关紧要了。

在处理从一个发行版到另一个发行版的计算时,事情开始变得复杂。

示例:“过去,购买金额超过100美元需要经理的批准,但从现在起,该门槛是50美元”。因此,我们有75美元的购买请求。需要批准吗?好吧,这取决于制定价格时生效的规则集。你要去哪里捕捉?

通常的做法是,事件日志不仅用于捕获模型的输入,而且还用于基于这些输入做出的决策。换句话说,一旦有了事件,您就不再需要业务规则来了解正在发生的事情。

答案 1 :(得分:1)

  

状态可以通过两种方式更改:要么由系统用户直接更改,要么由于系统中其他更改的结果。

然后,您应该在域事件中捕获此事件。从纯粹的逻辑观点来看,status发生更改的事实并不取决于以下原因:如果用户更改了它,则它更改了;如果系统更改了它,那么它也会更改(使用过的人会看到它已更改,对吗?)。因此,从状态的角度来看,它在任何情况下都会发生变化。

在您的域中,为什么更改status很重要,所以您应该在事件本身中捕获这一点。例如,事件可能看起来像这样:StatusChanged(enum newValue, bool changedByTheUser)

多亏了事件源,您之后才能在Aggregates或ReadModels中使用此信息(为什么更改)。例如,当有关自动状态更改的业务规则更改时,您可以使用以下代码忽略系统先前所做的更改:

if(!event.changedByTheUser and event.date < '2019-01-02'){ /* ignore it */}