How/where 在 DDD 和基于 CQRS/ES 的系统中加载不同 BC 中的实体值对象
How/where to load value object that is entity in different BC in DDD and CQRS/ES based system
我已经学习了这个很棒的教程:http://www.cqrs.nu/tutorial/cs/01-design 并尝试以同样的方式制作我的应用程序。
根据我之前的问题我知道,一个 BC 中的实体是什么可以表示为包含另一个 BC 中的实体标识符和可选的任何其他参数的值对象。 (我把这些标识符放到了 Core BC 中。)
现在,假设我有两个 BC:PlansEditor
和 Subscribing
。
在 PlansEditor
中,假设有 Editor
(有角色的人),当他使用 frequency
和 vip
等参数创建 Plan
时,然后创建 Plan
。
在 Subscribing
中,假设有 Customer
和一些可用的 Plan
,当客户订阅 Plan
时,就会创建 Subscription
。
这里的计划可能只是带有频率和 VIP 参数的 VO,因为订阅只需要它们(以保护不变量)。但是客户点击订阅计划并发送带有计划 ID 的请求。
因此,我以客户 ID 和他订阅的计划 ID 开始我的 BC 生命周期。我需要通过某处给定的标识符 load/create Plan
"value object"(这实际上是 PlansEditor
BC 中的实体)。
我应该在哪里以及如何在 Subscribing
BC 获得该计划 VO?
我想在应用层通过事件存储库 - 能够发送包含此值对象的 SubscribeCustomerToPlanCommand(Customer, Plan)
。但是 Subscribing
BC 然后需要知道 Plan
作为 PlansEditor
中的实体存在,以便加载它并将其转换为 Plan
作为 VO,这是不可接受的 - 一个 BC需要其他才能正常运行。
或者我应该只从一些读取模型中获取创建 Plan
VO 所需的信息,然后在应用程序层执行此操作,这样方便吗?或者如何以及在哪里? :)
据我所知,Plan
在这两种情况下都不是 VO。并不是因为一个 BC 对实体的生命周期具有权威,实体在其他上下文中成为 VO(它可以)。
如果下游上下文需要了解远程上下文中实体的生命周期,那么该实体也应该建模为下游上下文中的实体。
例如,我想 Plan
s 可以在某个时候停用,允许订阅这些是没有意义的?这将是一个很好的指标,表明 Plan
在 订阅 上下文中不是一个简单的值。
在 BC 集成方面有多种策略,但如果您更喜欢可用性而不是一致性,那么消息传递很可能是更好的选择。上游上下文将在消息传递基础结构上发布事件,这些事件将被下游上下文使用,从而使其保持实体状态的本地副本同步。
"BC would then need to know that Plan as entity in PlansEditor exists
in order to load it and translate it to Plan as VO, which is
unacceptable - one BC would need other to function properly"
任何集成策略都需要一定程度的耦合,但这种耦合应该在反腐败层中抽象出来。
我已经学习了这个很棒的教程:http://www.cqrs.nu/tutorial/cs/01-design 并尝试以同样的方式制作我的应用程序。
根据我之前的问题我知道,一个 BC 中的实体是什么可以表示为包含另一个 BC 中的实体标识符和可选的任何其他参数的值对象。 (我把这些标识符放到了 Core BC 中。)
现在,假设我有两个 BC:PlansEditor
和 Subscribing
。
在 PlansEditor
中,假设有 Editor
(有角色的人),当他使用 frequency
和 vip
等参数创建 Plan
时,然后创建 Plan
。
在 Subscribing
中,假设有 Customer
和一些可用的 Plan
,当客户订阅 Plan
时,就会创建 Subscription
。
这里的计划可能只是带有频率和 VIP 参数的 VO,因为订阅只需要它们(以保护不变量)。但是客户点击订阅计划并发送带有计划 ID 的请求。
因此,我以客户 ID 和他订阅的计划 ID 开始我的 BC 生命周期。我需要通过某处给定的标识符 load/create Plan
"value object"(这实际上是 PlansEditor
BC 中的实体)。
我应该在哪里以及如何在 Subscribing
BC 获得该计划 VO?
我想在应用层通过事件存储库 - 能够发送包含此值对象的 SubscribeCustomerToPlanCommand(Customer, Plan)
。但是 Subscribing
BC 然后需要知道 Plan
作为 PlansEditor
中的实体存在,以便加载它并将其转换为 Plan
作为 VO,这是不可接受的 - 一个 BC需要其他才能正常运行。
或者我应该只从一些读取模型中获取创建 Plan
VO 所需的信息,然后在应用程序层执行此操作,这样方便吗?或者如何以及在哪里? :)
据我所知,Plan
在这两种情况下都不是 VO。并不是因为一个 BC 对实体的生命周期具有权威,实体在其他上下文中成为 VO(它可以)。
如果下游上下文需要了解远程上下文中实体的生命周期,那么该实体也应该建模为下游上下文中的实体。
例如,我想 Plan
s 可以在某个时候停用,允许订阅这些是没有意义的?这将是一个很好的指标,表明 Plan
在 订阅 上下文中不是一个简单的值。
在 BC 集成方面有多种策略,但如果您更喜欢可用性而不是一致性,那么消息传递很可能是更好的选择。上游上下文将在消息传递基础结构上发布事件,这些事件将被下游上下文使用,从而使其保持实体状态的本地副本同步。
"BC would then need to know that Plan as entity in PlansEditor exists in order to load it and translate it to Plan as VO, which is unacceptable - one BC would need other to function properly"
任何集成策略都需要一定程度的耦合,但这种耦合应该在反腐败层中抽象出来。