除了以下情况是否对DDD完全适用的问题外,我想讨论一下并寻求建议:

鉴于我们有用户和组。用户有一个名字,一个组也有一个名字。用户可以加入请假组,也可以更改组。他们必须遵守的规则是:一个用户最多只能有2个组,一个组最多可以有10个用户。

您如何建模?到目前为止,我可以想到三个选择,其中每个选择都有其各自的优点和缺点:

  • 用户和组是实体,并且两者都是集合。 JoinSwitchLeave是组聚合上的命令。尽管这对于JoinLeave非常有效(因为它们仅指单个组),但不适用于Switch,因为它同时指向两个组,因此需要在单个事务中修改两个聚合不好
  • 用户和组是实体,并且两者都是集合。 JoinSwitchLeave是用户集合上的命令。这对所有三个用户都有效,并且很容易同时检查一个用户不在两个以上的组中,但是您如何检查不违反每个组最多10个用户的规则?
  • 用户和组是实体,都是聚合。但是,还有第三种聚合:关系。 JoinSwitchLeave现在是关系聚合上的命令。尽管这似乎是最好的方法(因为它为用户和组之间的关系提供了名称并使其变得明确),但现在我完全迷失了如何对约束进行建模。

  • 有人可以给我提示吗?

    如果只有两个约束之一,那就很容易了:然后,您可以将命令放入也有约束的集合中。但是如果双方都有约束,我就会迷失方向。有什么帮助吗?

    最佳答案

    您可以将group的实例交给用户,以使其检查包含聚集的不变量。然后,让用户知道它已加入该组,并让该组知道该用户已加入。

    class Application
      handle(UserWantsToJoinGroup command)
        user = users.withId(command.userId)
        group = groups.withId(command.groupId)
        user.join(group)
    
    class User
      join(Group g)
        if g.isFull throw
        if this.isMemberOf(g) throw
        if this.numberOfGroupsImIn >= 2 throw
    
        publish new JoinedGroup(this.userId, g.groupId)
    
      handle(JoinedGroup evt)
        // modify state
    
    class Group
      handle(JoinedGroup evt)
        // modifiy state
    

    07-24 09:37
    查看更多