域驱动设计-如何汇总回合制游戏

时间:2018-09-07 17:51:16

标签: dns domain-driven-design ddd-repositories aggregateroot

我正在设计公司业务中的游戏。这是一个回合制游戏。

不变式:

a)一个游戏至少有两个玩家,一个开始日期和另一个     属性。

b)每个玩家在游戏内玩一个回合。

c)成员     加入游戏后成为玩家。

d)成员可以是     0-n个游戏。

我的主要问题是如何汇总概念。

enter image description here

起初我认为该成员是其自身的集合。由于其他成员仅维护对该成员的引用。

稍后,Game可能是另一个集合(包括玩家和回合)的根。我可以保证:

  • 不变量a)创建时。
  • 不变量b)集合具有满足集合内所有条件所需的全部条件。
  • 不变量c)=>不对此集合负责

由于我真的很困,所以我想听听您的方法。

2 个答案:

答案 0 :(得分:1)

在回合制,交叉盘,跳棋,国际象棋,西洋双陆棋等基于回合的游戏中,我通常希望“游戏”合计包括代币/棋盘/画面的移动和当前位置。

要弄清游戏历史在内部是否一致,需要能够“一起”查看所有历史,以便发现矛盾。

一种查看方式是,注意到两个不同的成员资格通常彼此之间没有任何依赖关系,因此使它们成为聚合的不同实例是有意义的。如果一个游戏要由两个成员共享,那么它就不能真正属于任何一个成员,因此它必须是单独跟踪的某个第三集合。

答案 1 :(得分:1)

您做对了,有2个汇总,但是现在您需要了解原因。

成员聚合拥有成员的数据和行为。成员的含义,如何成为成员,何时可以更改其名称,何时可以解锁等。

游戏集合拥有游戏规则和两个玩家。它具有保护其不变式并将其显示在UI中所需的所有数据。它保护的不变式是:

  1. 在游戏开始之前,必须至少存在两个不同的玩家,并且一个成员只能在同一游戏中玩一次
  2. 每个玩家都一个接一个地移动
  3. 当玩家不在游戏中时,它就无法移动
  4. 依此类推

为了保护第二个不变式,游戏具有turn状态,该状态是指向下一个玩家的指针。但这是一个有趣的问题:什么是播放器,如何在代码中表示它?

玩家是其中一个成员的指针。它具有游戏集合或用户界面所需的所有属性。 Game Aggregate需要其ID,以便保护第一个不变变量(以检测重复的ID),以便加载会员玩的所有游戏,并在UI中显示玩家的名称,以便其他玩家知道他们在玩谁。

播放器似乎是一个实体,因为它具有ID和另一个属性(即名称),但这并不是因为它不拥有名称或名称的行为:成员何时以及如何更改它是名称由会员聚合控制,玩家的名称会更新,而无需在玩家身上加上任何文字(可能是在后台)。

从游戏的角度来看,玩家只是一个不可变的普通对象,其ID和名称为string。这是Value对象的理想选择。

因此,尽管成员是聚合根(这是实体的一种),但具有与成员相同的ID和名称的播放器不是实体,而是值对象。