如何在DDD中为用户和组建模?

时间:2014-02-13 13:08:01

标签: domain-driven-design

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

  

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

你如何塑造这个?到目前为止,我可以想到三个选项,每个选项都有各自的优点和缺点:

  1. 用户和组是实体,两者都是聚合。 JoinSwitchLeave是群组汇总上的命令。虽然这适用于JoinLeave(因为它们仅指单个组),但它不适用于Switch,因为它同时指两个组,并且因此需要在单个事务中修改两个聚合,这不太好。

  2. 用户和组是实体,两者都是聚合。 JoinSwitchLeave是用户聚合上的命令。这适用于所有三个,并且很容易检查用户同时不在两个以上的组中,但是如何检查每组最多10个用户的规则是否未被违反?

  3. 用户和组是实体,都是聚合。但也有第三个聚合:关系。 JoinSwitchLeave现在是关系聚合的命令。虽然这似乎是最好的方法(因为它给用户和组之间的关系一个名称并使其明确),我现在完全迷失了如何建模约束。

  4. 有人可以给我一个提示吗?

    如果只有两个约束中的一个,那么它将很容易:然后你可以将命令放到也具有约束的聚合中。但如果你对双方都有约束,那我就输了。有什么帮助吗?

1 个答案:

答案 0 :(得分:5)

您可以将一个组实例交给用户,让它检查包含聚合的不变量。然后让用户知道它已加入群组并让群组知道用户已加入。

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