DDD 跨限界上下文引用子实体
DDD referencing child entities across bounded contexts
假设我有一个具有 2 个聚合根的 "Directory" 有界上下文。公司和个人。公司有一个子实体集合 "Position",其中包含一个人的 ID 以及一些额外的值数据。
一切顺利。
现在我们去添加一个 "Article" 有界上下文和聚合根 JobAriticle。这需要一个从公司职位映射的联系人值对象。
所以知道你应该只引用聚合根我该怎么办?假设 Company 与 Position 的关系存在不变量,所以我不想拆分聚合。是否可以通过公司和职位 ID 通过反腐败层映射职位?或者我是否需要尝试拆分公司聚合。
如果 Position
在 "Article" 限界上下文的通用语言中是一个有意义的概念,那么 Position
应该是 "Article" 限界上下文中的 ValueObject 或 Entity .
如果你说 Contact
在 "Article" 有界上下文中是有意义的概念,但它需要以某种方式与 [=69= 中的 Position
相关联] bounded context,那么你需要思考那个关联的目的是什么:
- 在
JobArticle
上创建联系人之前是否需要验证职位是否存在?
- 是否有一些共享数据将在
Position
和 Contact
之间保持同步?
- 如果某个位置 archived/deleted 或因其他原因停止服务会怎样 - 您是否必须对所有联系人执行某些操作?
如果您需要在创建关联的联系人之前验证 Position
是否存在,那么 Position 隐式地在文章上下文的职责中发挥作用 - 所以我很想创建一个新的 Position
文章上下文中的实体并保持同步。
无论哪种方式,要将文章上下文中的某些内容与目录上下文中的相应实体相关联,您可以在名为 PositionCorrelation
的 "Article" 上下文中创建一个 ValueObject,它具有两个属性:
- CompanyId(全球唯一)
- PositionId(公司内本地唯一)
聚合应仅引用其他聚合根的规则并不意味着您不能也提供用于标识聚合内实体的信息。这只是意味着如果你想与其他实体互动,你应该 通过 聚合根,这意味着你必须 至少 有聚合根 ID。如果您然后使用本地 Id 要求公司对其其中一个职位做某事,那很好。
但是 - 请注意,通过采用这种方法,您将术语 "Position" 引入到 "Article" 有界上下文中,如果 "Position" 这个词可能会引起名称冲突在 "Article" 上下文中表示其他内容 - 例如也许它意味着文章中的位置(段落编号等)。如果是这种情况,你需要仔细考虑如何调用跨上下文标识符。
一种方法是,如果 Position
与 Contact
具有一对一的映射,那么您的两个属性可以是:
- 公司编号
- CompanyContactId
并且当在上下文之间集成时在反腐败层 (ACL) 保持同步时,将 CompanyContactId 和 PositionId(公司内的本地)值定义为同义值。这使每个 UL 内部保持一致,并在 ACL 中定义两者之间的关联。
假设我有一个具有 2 个聚合根的 "Directory" 有界上下文。公司和个人。公司有一个子实体集合 "Position",其中包含一个人的 ID 以及一些额外的值数据。
一切顺利。
现在我们去添加一个 "Article" 有界上下文和聚合根 JobAriticle。这需要一个从公司职位映射的联系人值对象。
所以知道你应该只引用聚合根我该怎么办?假设 Company 与 Position 的关系存在不变量,所以我不想拆分聚合。是否可以通过公司和职位 ID 通过反腐败层映射职位?或者我是否需要尝试拆分公司聚合。
如果 Position
在 "Article" 限界上下文的通用语言中是一个有意义的概念,那么 Position
应该是 "Article" 限界上下文中的 ValueObject 或 Entity .
如果你说 Contact
在 "Article" 有界上下文中是有意义的概念,但它需要以某种方式与 [=69= 中的 Position
相关联] bounded context,那么你需要思考那个关联的目的是什么:
- 在
JobArticle
上创建联系人之前是否需要验证职位是否存在? - 是否有一些共享数据将在
Position
和Contact
之间保持同步? - 如果某个位置 archived/deleted 或因其他原因停止服务会怎样 - 您是否必须对所有联系人执行某些操作?
如果您需要在创建关联的联系人之前验证 Position
是否存在,那么 Position 隐式地在文章上下文的职责中发挥作用 - 所以我很想创建一个新的 Position
文章上下文中的实体并保持同步。
无论哪种方式,要将文章上下文中的某些内容与目录上下文中的相应实体相关联,您可以在名为 PositionCorrelation
的 "Article" 上下文中创建一个 ValueObject,它具有两个属性:
- CompanyId(全球唯一)
- PositionId(公司内本地唯一)
聚合应仅引用其他聚合根的规则并不意味着您不能也提供用于标识聚合内实体的信息。这只是意味着如果你想与其他实体互动,你应该 通过 聚合根,这意味着你必须 至少 有聚合根 ID。如果您然后使用本地 Id 要求公司对其其中一个职位做某事,那很好。
但是 - 请注意,通过采用这种方法,您将术语 "Position" 引入到 "Article" 有界上下文中,如果 "Position" 这个词可能会引起名称冲突在 "Article" 上下文中表示其他内容 - 例如也许它意味着文章中的位置(段落编号等)。如果是这种情况,你需要仔细考虑如何调用跨上下文标识符。
一种方法是,如果 Position
与 Contact
具有一对一的映射,那么您的两个属性可以是:
- 公司编号
- CompanyContactId
并且当在上下文之间集成时在反腐败层 (ACL) 保持同步时,将 CompanyContactId 和 PositionId(公司内的本地)值定义为同义值。这使每个 UL 内部保持一致,并在 ACL 中定义两者之间的关联。