CQRS + ES中的对象应该在哪里进行完全初始化:在构造函数中,还是在应用第一个事件时?
在OOP社区中似乎已经达成广泛的共识,即类构造函数不应将对象部分或什至完全未初始化。 我所说的“初始化”是什么意思?粗略地讲,原子过程将新创建的对象带入其所有类不变式都成立的状态。它应该是发生在对象上的第一件事(每个对象只能运行一次),并且任何内容都不应该拥有未初始化的对象。(因此,经常建议在类构造函数中执行对象初始化。出于同样的原因,Initialize方法常常被皱眉,因为这些方法打破了原子性并使得可以持有和使用尚未使用的对象成为可能。处于定义良好的状态。) 问题:当CQRS与事件源(CQRS + ES)结合使用时,对象的所有状态变化都被捕获在一系列有序的事件(事件流)中,我想知道对象何时真正达到完全初始化的状态:在类构造函数的末尾,还是在将第一个事件应用于对象之后? 注意:我避免使用“聚合根”一词。如果愿意,在阅读“对象”时将其替换。 讨论示例:假定每个对象由某个不透明Id值唯一标识(请考虑GUID)。可以使用相同的Id值在事件存储中标识表示该对象状态变化的事件流:(不用担心正确的事件顺序。) interface IEventStore { IEnumerable<IEvent> GetEventsOfObject(Id objectId); } 进一步假设有两种对象类型Customer和ShoppingCart。让我们关注ShoppingCart:创建时,购物车为空,必须与一个客户完全关联。最后一点是类不变式:ShoppingCart与a无关的对象Customer处于无效状态。 在传统的OOP中,可以在构造函数中对此建模: partial class ShoppingCart { public Id Id { get; private set; } public Customer Customer { get; private set; } public ShoppingCart(Id id, Customer customer) { this.Id = id; this.Customer = customer; } } …