如何实施聚合根的规则?

Myl*_*Rip 9 domain-driven-design

在搜索网络时,我遇到了Eric Evans的书中的一系列规则,这些规则应该针对聚合强制执行:

  1. 根实体具有全局标识,并且最终负责检查不变量
  2. 根实体具有全局身份.边界内的实体具有本地标识,仅在Aggregate中唯一.
  3. 除了根实体之外,聚合边界之外的任何内容都不能包含对内部任何内容的引用.根实体可以将对内部实体的引用传递给其他对象,但它们只能瞬时使用它们(在单个方法或块中).
  4. 只能使用数据库查询直接获取聚合根.其他一切都必须通过遍历来完成.
  5. Aggregate中的对象可以保存对其他Aggregate根的引用.
  6. 删除操作必须一次性删除聚合边界内的所有内容
  7. 当提交对Aggregate边界内的任何对象的更改时,必须满足整个Aggregate的所有不变量.

这一切似乎在理论上很好,但我看不出这些规则将被强制在现实世界中.

以规则3为例.一旦根实体为外部对象提供了对内部实体的引用,那么什么是使该外部对象保持超出单个方法或块的引用?

(如果执行此操作是特定于平台的,我将有兴趣了解如何在C#/ .NET/NHibernate环境中强制执行此操作.)

Ric*_*son 6

我不认为你应该让聚合给你的外部代码访问它的实体.

你告诉你的汇总你想要发生什么,它会处理它.

如果我们有一个聚合:汽车.我们不关心汽油和轮子,我们只是开车.我们向汽车询问有关事情的事情并且在不提及内部参考的情况下回答.

我们问:我们有汽油吗?是.不:给我坦克物品,这样我就可以检查一下我们是否有汽油.


Szy*_*ega -1

我最喜欢的实施 DDD 模式和实践的方式是不断地教育人们了解他们的价值。然而,有时我拥有更严格的工具。

我自己还没有这样做,但在我看来,FluentNHibernate 可能是强制聚合属性的一个很好的工具。

您的示例可以通过使用“IAggregateRoot”标记接口标记所有聚合根和使用“IEntity”标记接口标记非根实体来实现。然后,您的自定义 FNH 约定将检查标记为 IEntity 引用实体 IEntity 的实体,并在找到时发出错误信号(例如引发异常)。

这有什么意义吗?