Events 哪些对象负责维护聚合之间的引用?

Events 哪些对象负责维护聚合之间的引用?,events,domain-driven-design,separation-of-concerns,Events,Domain Driven Design,Separation Of Concerns,假设我有一个聚合,Ticket。一张票据将分配一个部门和一个或多个员工 当实例化票证时,票证工厂是否应负责确保使用有效/存在的部门和员工创建票证 同样,当解除部门或员工时,什么负责确保将新的部门或员工分配给票证,以保持其不变?域中是否存在负责退役的服务,或者在这种情况下是否应采用最终一致性或某种形式的事件侦听 TicketFactory将声明,为了创建Ticket,您需要同时引用部门和员工。它不会核实这些事实是否存在。调用代码负责获取适当的引用 如果使用最终一致性,则部门和员工的退役将发布指示退

假设我有一个聚合,
Ticket
。一张
票据
将分配一个
部门
和一个或多个
员工

  • 当实例化
    票证
    时,
    票证工厂
    是否应负责确保使用有效/存在的
    部门
    员工
    创建
    票证

  • 同样,当解除
    部门
    员工
    时,什么负责确保将新的
    部门
    员工
    分配给
    票证
    ,以保持其不变?域中是否存在负责退役的服务,或者在这种情况下是否应采用最终一致性或某种形式的事件侦听

  • TicketFactory
    将声明,为了创建
    Ticket
    ,您需要同时引用
    部门
    员工
    。它不会核实这些事实是否存在。调用代码负责获取适当的引用

  • 如果使用最终一致性,则
    部门
    员工
    的退役将发布指示退役的事件。将有一个与
    票证相关联的处理程序,该处理程序将订阅该事件,并分配新的部门和员工,或向任务发送某种类型的警告


  • 请看一看,了解更多信息。

    我最近开始研究DDD,因此遇到了您提到的一些问题

  • 我认为
    TicketFactory
    应该始终返回已验证/正确构建的
    Ticket
    实例。如果您的模型很复杂,您可以使用域服务来验证给定的
    部门
    员工
    是否可以附加到该模型,然后工厂使用该模型。否则,你可以把它全部放在工厂里。但是从工厂出来的应该是一张合适的票

  • 例如,如果只有
    Ticket
    知道另外两个,那么使用
    Department
    Employee
    repos的域服务将完成这项工作。如果关系是双向的,则可以利用事件源。此外,如果它确实是一个应该在域模型中捕获的事件,并且具有除重新洗牌以外的其他后果,则可以将其中一个处理程序附加到此事件,使其成为
    InvalidTicketHandler
    。但是如果它是一个小规模的东西,保持简单,只要有一个维护不变量的域服务

  • 旁注:如果
    部门
    和/或
    员工
    本身是聚合的,那么您可以通过其标识符(例如员工的公司ID或部门ID代码)在
    票据
    中引用它们。这样,您将更容易实现一致性,因为您不会跨越不同聚合之间的一致性边界

  • 工厂负责确保其创建的对象或集合满足所有不变量;但是,在删除应用于该对象之外的对象的规则之前,您应该始终三思而后行。工厂可以将不变检查委托给产品,这通常是最好的。[领域驱动设计:解决软件核心的复杂性]

  • A取决于问题类型,但从外观上看,它似乎是应用程序层功能的一个很好的候选者,尽管我不会选择事件解决方案,因为我发现它只适用于层之间,而不适用于同一层中的对象之间


  • 我不明白为什么工厂不能确保聚合包含有效的引用(甚至不保证代理)。你能解释一下吗?第2点对我来说很有意义;我已经可以看到多个可能的处理程序来解除员工的职务(向其他员工发送电子邮件、将票据移动到队列池、更新目录)。此外,感谢您提供的链接——在开始阅读Eric Evans的书之前,我已经阅读了这些文章。谢谢你提醒我,第二个特别让我想起了一些事情,尽管我不确定我是否同意使用全局ID而不是对象引用(即使只是一个虚拟代理)我很快需要再次通读埃文斯的书,看看我是否还学到了其他东西。工厂要能够验证其他聚合的存在,就需要访问它们的存储库——另一种依赖关系。由于应用程序服务已经引用了存储库或其他服务,它们应该负责提供适当的ID。我几乎可以理解为什么一个应用程序服务会像Vernon建议的那样只使用另一个聚合的ID——这当然消除了依赖性。但是,这是否也免除了确保从域到应用层满足所有不变量的责任?我认为域层的全部要点是封装所有这些业务规则?聚合只负责它自己的不变量,而不负责它可能引用的其他聚合。与标识引用相反,使用直接对象引用可能会在单个事务中修改两个聚合。由于各种原因,这可能会产生问题。1。我同意,这是工厂的一个决定性特征(它生产正确组装的骨料);正如我现在所看到的,如果我添加一些关于可以将多少项目分配给员工或部门之类的限制,那么添加的域服务可能会带来好处。2.我完全不知道这样的域服务将如何被调用。在退役过程中,常见的使用场景是什么?乍一看,可能不止这些