oop - 事件溯源中的值对象

标签 oop domain-driven-design event-sourcing value-objects

事件源域模型中是否有值对象的位置?

让我们定义一个 值对象作为具有不可变状态的对象,保护其不变量并且没有特定标识符。

事件来源 在这种情况下,领域模型是一个完全或部分源自事件的领域,这意味着它的当前状态可以通过应用过去发生的所有事件得出。事件本身被认为是不可变的,即使随着时间的推移也是如此。

关于the validity of using value objects within events的争论已经发生- 这个问题更进一步:Do value objects have a place in event source domain在所有 ?

使用值对象的(潜在)问题是,以不变量被收紧的方式改变域变得相当棘手。

这种情况的一个例子是有一个 Username值对象,唯一的限制是名称必须介于 2 到 16 个字符之间。

虽然这已经运行了一段时间,但公司决定只允许至少 5 个字符的用户名。
迁移期开始,名称少于 5 个字符的用户将被要求更新其名称。

让我们说这个过程是成功的,应用了更正事件,每个人都很高兴。
我们收紧了对 Username 的限制值对象至少需要 5 个字符。

有一段时间每个人都很高兴,但后来我们发现快照有问题并重播所有事件。

我们现在面临来自 Username 的异常。对象:通过加载历史数据,我们打破了我们领域的不变量。

一个值对象的规则追溯申请 - 这是否使它们本质上不适合事件溯源?是否值得应用值对象的版本控制?有没有更简单的方法来避免这些问题?

最佳答案

我会说,那一刻你重新定义了什么 Username意味着,并且您不以某种方式迁移历史数据,您实际上已经创建了 2 个不同的 Username意义。

因为这个词有 2 种不同的含义,所以您必须以某种方式在代码中明确表示。 “版本控制”是一种方式,虽然我不会使用这种通用解决方案,但有不同的建模选项。

您可以明确指出“用户名”的历史就是这样,一段历史。因此,例如创建一个 HistoricUsername ,这是事件源对象,如果需要,甚至可以是值对象。并创建一个 Username它始终是具有最新规则的用户名,它根本不持久化,而是从 HistoricUsername 创建的如果可以。

有些人建议有时从对象中提取“规则”,然后再重新应用。这样对象本身在任何时候都是有效的,你可以要求它根据可能改变的规则来验证自己。我不是很喜欢这些类型的解决方案,但它是一种选择,而且 Username仍然是一个值对象。

所以问题并不是真正的值对象不适合事件溯源,只是建模必须更准确。

关于oop - 事件溯源中的值对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52356127/

相关文章:

oop - 如何设计业务逻辑层

delphi - 如何使用dunit的DUnitWizard中包含的XPObserver单元来实现观察者模式,甚至MVC模式?

c# - 应该使用方法参数还是通过引用将命令信息传递给聚合?

nservicebus - 如何创建使用不同传输的单个 NServiceBus 端点?

publish-subscribe - CQRS + 事件溯源 : (is it correct that) Commands are generally communicated point-to-point, 而领域事件通过发布/订阅进行通信?

c++ - 派生类的一些问题

c++ - 一种克服对象切片的方法

domain-driven-design - 如何在DDD上使用继承

rest - CQRS 和 REST HATEOAS 不匹配

database - 对基于集合的 sql 数据操作操作的代码列表进行建模