Domain driven design 在基于DDD和CQRS/ES的系统中,如何/在何处加载不同BC中的实体值对象
我已经完成了这个很棒的教程:并尝试用同样的方法来做我的应用程序 根据我前面的问题,我知道一个BC中的实体可以表示为值对象,该值对象包含另一个BC中实体的标识符以及任意其他参数。(我将这些标识符放在核心BC中。) 现在,假设我有两个BC:Domain driven design 在基于DDD和CQRS/ES的系统中,如何/在何处加载不同BC中的实体值对象,domain-driven-design,cqrs,event-sourcing,Domain Driven Design,Cqrs,Event Sourcing,我已经完成了这个很棒的教程:并尝试用同样的方法来做我的应用程序 根据我前面的问题,我知道一个BC中的实体可以表示为值对象,该值对象包含另一个BC中实体的标识符以及任意其他参数。(我将这些标识符放在核心BC中。) 现在,假设我有两个BC:PlansEditor和订阅 在PlansEditor中,如果存在编辑器(具有角色的人员),当他使用一些参数创建计划时,如频率和vip,则创建计划 在订阅中,如果存在客户和一些可用的计划,当客户订阅计划时,将创建订阅 这里的计划可能只是带有频率和VIP参数的VO,
PlansEditor
和订阅
在PlansEditor
中,如果存在编辑器
(具有角色的人员),当他使用一些参数创建计划
时,如频率
和vip
,则创建计划
在订阅
中,如果存在客户
和一些可用的计划
,当客户订阅计划
时,将创建订阅
这里的计划可能只是带有频率和VIP参数的VO,因为订阅只需要它们(以保护不变量)。但客户单击以订阅计划,并发送id为计划的请求
所以我用客户id和他订阅的计划id开始我的BC生命周期。我需要通过某个给定的标识符加载/创建计划
的“值对象”(实际上是计划编辑器
BC中的实体)
我应该在哪里以及如何在订阅中获得该计划VO?
BC?
我在应用程序层通过事件存储库进行思考,以便能够发送subscribeCustomerToLanCommand(客户,计划)
包含此值对象。但是订阅
BC需要知道计划
作为计划编辑器
中的实体存在,以便加载它并将其转换为计划
作为VO,这是不可接受的-一个BC需要另一个BC才能正常工作
或者,我应该从一些read模型中获取创建Plan
VO所需的信息,然后在应用程序层中这样做,这样方便吗?或者如何以及在哪里?:) 据我所知,计划
在这两种情况下都不是VO。并不是因为一个BC拥有实体生命周期的权限,该实体才在其他上下文中成为VO(它可以)
如果下游上下文需要了解远程上下文中实体的生命周期,那么该实体可能也应该作为下游上下文中的实体进行建模
例如,我假设计划
s可以在某个时候停用,并且允许订阅这些计划没有意义?这将是一个很好的指标,表明计划
在订阅上下文中不是一个简单的值
BCs集成有多种策略,但如果您更喜欢可用性而不是一致性,那么消息传递很可能是更好的选择。上游上下文将在消息传递基础结构上发布事件,这些事件将被下游上下文使用,从而使其保持实体状态的本地副本同步
“然后,BC需要知道PlansEditor中的Plan作为实体存在
以便加载它并将其转换为计划VO,即
不可接受-一个BC需要另一个BC才能正常工作”
任何集成策略都需要某种程度的耦合,但这种耦合应该在反腐败层中抽象出来。实际上,当编辑器删除计划时,订阅BC中该计划的所有订阅方都应该使用订阅时使用的相同参数继续订阅(任何)计划。不应只允许新订阅者订阅,因为它不存在(在PlansEditor
BC中)。但在我看来,在订阅BC时维护Plan
实体似乎太复杂了,因为我很满意PlansEditor
BC中Plan
的状态在订阅时的特定时间实际复制到Plan
VO中。@Tom well,在这种情况下,Plan
可能是一个VO,您仍然可以通过作为订阅者上下文反腐败层一部分的服务获取该VO。请记住,这两个上下文之间不可能有很强的一致性(例如,客户可能订阅了刚刚停用的计划)。添加my ZAR0.02:)---同意,实体不一定是下游的VO,但您可能对该概念有不同的表示。。。所以可能是一个订阅计划或类似的计划。这意味着上游BC仍然是记录系统,您应该在一个VO中处理属于该BC的所有属性,因为您不应该更改它们,而应该使用集成模式在下游更新它们。您可以自由更改属于下游BC的值。@EbenRoux该概念在两种上下文中都可以命名为Plan
,但仍然是不同的表示形式。你订阅了计划
,而不是订阅计划
@plalx太好了,谢谢你,反腐败层解决了我的问题!它还把我带到了上下文地图和我刚交付的埃文的大蓝皮书中的整个第14章。这种方法中的另一个缺失部分被发现:)