聚合之间的业务规则协调

时间:2018-11-16 02:13:22

标签: domain-driven-design

我正在设计一个用于居住大厅的访客登记系统。居民可以办理入住手续,但前提是必须满足这两个条件。  1.一位居民一次只能入住2位客人  2.客人只能与一位居民签到

签到过程导致访问。

我在弄清楚应该在哪里实施这些规则时遇到了麻烦。我从这里开始

var visit = resident.checkin(guest);

但这意味着我要在一项操作中修改(或创建)三个聚合:

  • 居民(入住人数的递增#)
  • 客人(将他们设置为签入)
  • 访问=已创建

我看不到领域中的概念可以建模为可容纳这些规则的集合。居民和客人不在拜访(或其他拜访)之外,因此不能用其他集合包裹。

我想到了一个传奇,但最终以在域中没有意义的步骤结束(例如分别检查学生和来宾以查看是否失败)。

我可以使用一些指导吗?我的造型刚刚结束吗?

3 个答案:

答案 0 :(得分:0)

在我看来,应该将“居民和访客”的签入状态视为第三次AR的一部分,并且在确认访问后就应该增加“居民”中的增量字段。

方法1:

  

我看不到领域中的概念可以建模为可容纳这些规则的集合。居民和客人不在拜访(或其他拜访)之外,因此不能用其他集合包裹。

这并不意味着您的访问不能保存对居民和来宾的引用。 如果此第三次汇总是“访问”,并且具有状态(例如,待审核,已确认等),则可以以同步方式验证状态,并按照规则命令遍历状态。

方法2-为此使用事件:

有很多方法可以在架构上集成事件。事件源和CQRS在这里可能是一个很好的选择,因为它将改变您对AR,实体尤其是状态变化的看法。

CQRS简短定义:

  

将所有对应用程序状态的更改捕获为一系列事件

无论您在1到2之间选择什么,都应该将“访问”验证视为单独的内容。居民不应一次验证有多少位客人,客人不应验证“他”是否一次在两个地方。这些都是与访问相关的业务规则。

一些链接:  I've recently answered a DDD question in a similar domain  CQRS's "official site" by Greg Young  Docs on CQRS by Greg Young  Martin Fowler's notes on Event Sourcing  When to avoid CQRS?  Tons of videos and presentations on the subject

答案 1 :(得分:0)

在并发访问和一致性方面,创建新的聚合B作为现有聚合A交易的一部分通常不是问题(因为还没有人知道B)。在这里,您对Visits的数量有一个额外的不变性,这可能是一个例外,但是它是在Resident中强制执行的,并且Resident是创建访问的唯一入口点,因此所有内容归结为对Resident的修改,这是安全的并发方式。

然后,您对一个访客一次可以访问多少次有全局限制。该问题已在SO上得到了多次解答,但我首先建议您与您的领域专家讨论该规则及其可能的变化,因为这之间存在很大的可能性(最终一致性,手动干预等) “必须强制执行约束并立即保持一致” “规则无用”

答案 2 :(得分:0)

住宿大厅-汇总根(AR)

来宾-实体

居民-实体

访问-值对象(访问列表)

AR命令:

  1. CheckInGuestCmd (访客,居民)
  2. CheckOutGuestCmd (来宾)

第一个命令将检查访问并执行不变量,而不是添加访问

第二个命令将删除现有访问(如果存在)