【发布时间】:2021-03-21 19:15:05
【问题描述】:
我正在尝试使用领域驱动设计规则和模式开发我的第一个应用程序。
在我的业务场景中,我必须管理客户列表并跟踪发送到特定客户目的地的所有包裹。 所以,按照规则,结果是:
- 客户是一个实体,也是一个 AggregateRoot。
- 目标是客户的子实体(因为没有客户就没有意义)
- 包是一个实体。它也是另一个 AggregateRoot 因为是不同的事务边界 我使用 AddDestination(string destinationName ...) 方法开发了客户聚合,该方法负责为客户创建新目标。
现在我需要开发 Package 类,我必须在其中维护对包裹运送目的地的引用。按照 DDD 规则,我不能直接引用子实体 id,因为我不能引用另一个聚合的子实体。
我该怎么办?
- 我是否必须使用 Destination 的所需数据创建一个新的 ValueObejct 并公开它? (通过这种方式,我能够保留只能通过 Customer AggregateRoot 以书面形式访问的 Destionation 的封装和规则)。通过这种方式,外部类可以访问目标的字段并使用这些字段执行逻辑/检查,但不能更改目标的状态。
- 我是否必须添加 DestinationNumber 字段(在客户中渐进式),创建一个包含 CustomerId 和 DestinationNumber 的 ValueObject 并在 Package 聚合中使用它?
- ?
有人可以帮我吗?请详细说明回复,因为我想了解更多这种情况。
【问题讨论】:
-
您写道,没有客户,目的地就没有意义,后来听起来您只想指向目的地。哪一个是真的?根据答案,我建议要么将所有目标数据作为值对象复制到 Package 中(如果客户在这里无关紧要,则选择 1)或存储 CustomerId + DestinationNumber 组合(如果没有目的地没有意义,则选择 2客户)。
-
谢谢@urmaul 的回复。没有客户,我的通用语言中的目的地没有意义,因为每个目的地都与一个客户相关(而客户可以有多个目的地)。目的地有自己的 id所以我可以引用它还是不能,因为没有客户,Destination 就没有意义?
-
我的数据库架构是这样的:TAB_Customers(ID, name), TAB_Destionations(ID, CustomerId, name), TAB_Packages(ID, DestinationId, Date)。如果我只在我的普遍语言中引入 DestinationNumber 是可以的,因为我需要在我的值对象中使用它?将目的地视为客户的子实体,我做错了吗?因为我只能从我的包中引用它,所以我需要将它视为另一个 AggregateRoot?