2013-05-02 45 views
1

我想用DDD模拟场景,我们有团队,开发人员和团队应该完成的任务。如何访问另一个聚合中的实体?

基本上,我假定:

  • Team是一个实体(如它可以改变,例如,通过让上板新开发者)
  • Developer是一个实体,以及(因为它是重要的,其开发商做了什么)
  • Story是一个实体(因为它可以改变,例如,通过预约的工作项目上的故事)
  • Work是一个值对象(因为它不能改变,一旦它已经完成)

什么是相当明显的是,Team是一个聚合,包含Developer实体。另外,Story是一个聚合,包含Work值对象。

所以,在开始的时候,我开始用下面的代码:

var team = Team.FoundTeam(); 
team.WelcomeDeveloper("John Doe"); 
team.WelcomeDeveloper("Jane Doe"); 

var story = Story.WriteDownStory("Publish website"); 
story.AssignTeam(team); 

到目前为止,一切都很好。现在,下一步,我想收取故事的工作。基本上这可能如此简单:

story.ChargeWork(new TimeSpan(2, 0, 0)); 

不幸的是,现在需要将工作分配给开发人员。这是我的问题:我如何建模?我不能做的是:

story.ChargeWork("Jane Doe", new TimeSpan(2, 0, 0)); 

如果有两个同名的开发人员,这会失败。我如何分配特定的开发人员实体而无需访问它(因为只能使用Team聚合根访问开发人员)?

对此有何暗示?

我的模型是完全破碎的,还是我错过了一些重要的东西?

+2

我看到您已将问题标记为“数据建模”。这是你的想法告诉你的一个暗示:你正在建模数据(状态),而不是建模业务流程即DDD。 – MikeSW 2013-05-02 08:53:56

+0

感谢您的提示!这比第一眼看起来更有价值,因此+1 :-) – 2013-05-02 09:38:32

回答

2

您可以使用ID作为参考。

var jane = developer.findByName('Jane Doe'); 
story.ChargeWork(jane.id, new TimeSpan(2,0,0)); 
+0

但是,我会将'Team'聚合体中的实体暴露给外部,不是吗? – 2013-05-02 08:43:53

+2

没有域驱动的设计禁止一个对象持有另一个聚合内的实体_object reference_。这并不意味着你不能存储对象的_identity_的引用,这就是这个答案的作用。 – 2013-05-02 18:56:59

2

除了领域专家可以告诉你模型是否坏了,但我可以告诉你一些IMO弹出的东西。

团队是聚合在一起的开发人员的根(不是聚合)。但是,开发人员在团队中的定义有界上下文可能仅仅是一个Id和一些相关行为,也就是说它不是一个相同的开发者实体,它是在其自身有界的上下文中(在团队之外)的聚合根。

现在,Team实体非常简单地执行独特的开发人员。另外,我认为团队应该向开发者收费(仍然困惑什么是收费意味着)而不是故事。当你开始执行技术规则(X是实体,Y是值对象,我必须有一个存储库等)时,模型应该紧跟现实生活过程,你走错了路。

+0

+1我认为你已经在不同背景下突出了开发人员的头脑。开发人员很可能在许多团队中工作 - 在这种情况下,关系会逆转,其中Developer是聚合根,并且包含一个或多个团队。 OP已经暗示了有限的背景 - 在故事/工作环境中,开发人员只是一个姓名字符串。我想补充一点,引入一些跨上下文一致的自然或代理键通常是一个好主意,并且可能在跨越上下文时作为参考键 - 正如mattwagl所暗示的那样。 – MattDavey 2013-05-02 12:15:03

相关问题