0

我正在学习 DDD 概念并加强我的理解,我正在研究一些现实世界的例子。

我知道聚合应该只有一个通过根实体的入口点,聚合应该只有一个存储库(如果我完全理解错误,请纠正我)

现在假设有特定类型的消耗品,这些消耗品是从配送中心发送的。发送特定类型的消耗品取决于它们的数量,我的意思是,如果其中一位消费者的 A 型和 B 型的评论数量为 10,并且这些物品数量低于 10,那么配送中心会发送 A 型和 B 型消耗品。在这里,发送者和消费者都想跟踪发送的包裹在哪里,或者它是否已经交付或发送。

所以在这里,作为实体,我们有:

  1. 消耗品
  2. 消耗品类型
  3. ConsumableActivity
  4. 包裹
  5. 包裹物品
  6. 消费者

我对前三个实体感到困惑:哪个应该是聚合根?乍一看,消耗品似乎是一个强有力的候选者,但另一方面,我们并不关心每一个消耗品,我们只对它们的数量感兴趣。我们没有记录 10 种不同的 A 类消耗品,而只有一个 A 类记录,其数量根据活动而变化。在这一点上,Consumable 实体似乎是多余的,仅通过查看活动我们就可以得出数量。例如从头开始:

  1. 中心创造“A型”10
  2. 中心创造“B型”20
  3. 中心发送“Type A” 5 ConsumerId=25
  4. 中心发送“Type B”15 ConsumerId=25
  5. ConsumerId=25 接收“A 型” 5
  6. ConsumerId=25 接收“B型” 15
  7. ConsumerId=25 消费“A 型” 3
  8. ConsumerId=25 消费“B型”1
  9. ConsumerId=25 消费“A 型”2

在这里,我们可以得出,中心有 5 个 A 型和 B 型消耗品,而现在 id 为 25 的消费者有 0 个 A 型和 14 种 B 型消耗品。

当然这不是一个有效的方法,因为在有更多的活动之后,需要一些时间来得出消耗品的数量,因此对于消费者和配送中心的每种消耗品类型都应该有一个静态数量字段,我们可以在其中阅读当前数量一次。

我希望你明白我为什么感到困惑,消耗品实体看起来像一个根实体,但实际上它并不适合成为一个根实体,如果它也不是一个实体的话。

谁能建议我对此设计进行一些改进或进一步阅读建议,这些建议不仅限于客户-产品-订单-订单的噩梦吗?


编辑:与 Consumable 和 ConsumableType 有什么关系?如果我想对 ConsumableType 进行 CRUD 操作(让用户添加新类型、更改或删除它们)但根实体是 Consumable 怎么办。为了 DDD 保持数据完整性,我们不应该加载根实体存储库以外的任何存储库。

编辑 2:考虑 Product 实体及其 Category 实体。产品似乎是根实体,但我们知道产品不能没有类别而存在。那么类别实体是根吗?如果是这样,根据 DDD 规则,我们只能通过遍历来访问产品。但在我们的上下文中,产品是我们关注的焦点。然后假设我们有两个聚合:Product Aggregate 和 Category Aggregate。但是这次我们违反了数据完整性,因为可以删除一个类别而不删除具有该类别的产品。所以我很困惑,找不到合适的解决方案。

4

1 回答 1

2

我对前三个实体感到困惑:哪个应该是聚合根?

我要说的是,您的聚合很可能是 Package,即使这个示例有可能被拆分为两个或多个单独的有界上下文。(创造和订单履行是自然界限)

与 Consumable 和 ConsumableType 有什么关系?

这取决于您的有界上下文。除了由“A”或“B”指定之外,在不了解 ConsumableType 的情况下,我不得不说它很可能是 Consumable 的值对象。

如果我想对 ConsumableType 进行 CRUD 操作(让用户添加新类型、更改或删除它们)但根实体是 Consumable 怎么办?

这很可能是完全不同的有界上下文(某个经理的上下文或不属于我们正在建模的一般工作流程的内容),建议对此上下文进行更多调查。

[不同的例子]

那么类别实体是根吗?

聚合根是上下文中的用户与之交互的内容。假设很多,因为您没有完全解释此示例中的上下文,很可能 Product 是聚合根,因为这是用户最关心的。与上面的示例相同,Product 将有一个存储库,该存储库会将其分配的类别加载给它。在这种情况下,加载类别或层次结构列表最好由域服务提供,因为它不属于任何特定的实体实例。

[另一个例子]

在您的第一种情况下,例如系统管理员如何列出所有可用的字体颜色或添加新字体颜色?

同样,系统管理员的上下文与选择字体颜色的用户的上下文不同。请记住,每个上下文都是一个工作流。在复杂的工作流中,同一上下文中可以有多个用户,但对于管理员可能执行的 CRUD 操作等简单的工作流,通常这种类型的工作流只有一个角色。在系统管理员下,AvailableFontColor 可能是在内容装饰选项管理有界上下文中具有颜色值属性的实体。

谁能建议我对此设计进行一些改进或进一步阅读建议,这些建议不仅限于客户-产品-订单-订单的噩梦吗?

我建议您更多地了解有界上下文以及为什么它们是您在建模业务领域时最有用(有时也是最阻碍)的工具之一。此外,不要期望在一周内将其完善为一门科学。

8 年多来,我一直在使用各种技术对软件进行建模,但有时我仍然无法确定我是否正确地建模了某些东西。我认为 DDD 的最大好处之一是它鼓励您接受这样一个事实,即您可能不会从一开始就正确建模,因此您应该更容易地更改模型并经常重构,因为您更多地了解您的领域,而不是而不是仅仅使用你所拥有的并最终在你的原始模型周围产生 15 个不同的令人费解的结块,因为你从一开始就没有完全理解这个领域。

于 2013-01-09T21:26:25.547 回答