Php ddd-如何分离有界上下文和共享事件?
实际上,我正在读一本名为“PHP中的DDD”的书,以帮助我理解域驱动设计。到目前为止,一切都很好,但我很难理解如何在不耦合有界上下文的情况下实现一个特定主题:域事件 比方说,我必须遵守BCs:Php ddd-如何分离有界上下文和共享事件?,php,events,domain-driven-design,separation-of-concerns,bounded-contexts,Php,Events,Domain Driven Design,Separation Of Concerns,Bounded Contexts,实际上,我正在读一本名为“PHP中的DDD”的书,以帮助我理解域驱动设计。到目前为止,一切都很好,但我很难理解如何在不耦合有界上下文的情况下实现一个特定主题:域事件 比方说,我必须遵守BCs: 付款:处理发票生成、发送给客户等 订单:处理订单的创建、状态等 放置订单时,将调度OrderCreated事件。 PaymentsBC通过订户捕获此事件,并创建发票 问题是,如果我想完全分离两个BC,那么既然两个BC都使用它,orderplacted事件应该在哪里活动?它应该住在两个BC之外吗?在他们
- 付款:处理发票生成、发送给客户等
- 订单:处理订单的创建、状态等
订单
时,将调度OrderCreated
事件。
Payments
BC通过订户捕获此事件,并创建发票
问题是,如果我想完全分离两个BC,那么既然两个BC都使用它,orderplacted
事件应该在哪里活动?它应该住在两个BC之外吗?在他们两个人身上?如果我想将Invoices模块作为独立模块部署,而不访问Orders模块及其OrderPlaced事件定义,会不会导致一些致命错误
提前感谢您的回答
问题是,如果我想完全分离两个BC,OrderPlaced事件应该在哪里发生,因为它被两个BC使用?它应该住在两个BC之外吗?在他们两个人身上
我会将事件存储在拥有它的上下文中,即Orders上下文。你打算如何区分上下文?它是物理/网络边界分离,还是只是概念上的
如果我想将Invoices模块作为独立模块部署,而不访问Orders模块及其OrderPlaced事件定义,会不会导致一些致命错误
这取决于您对OrderPlaced所做的操作。如果您是从某种事件流订阅它,然后在InvoicesBC中通过将其转换为内部到发票的概念来对其作出反应,那么您可能不会有问题,因为您无法部署订阅服务器。如果您在InvoicesBC中的代码可以运行,而不必知道OrderPlaced,那么您就可以了
一般来说,有几种方法可以解决此问题:
问题是
付款
BC是否必须创建发票,因为顾名思义,它应该关注付款
,而不是订单
或发票
也许是这样的:
Orders -> 'order created' -> Payments -> 'payment done' -> Orders -> 'invoice created'
虽然答案已被接受,但我仍想补充我的意见:) 您当前BCs整合的方式是直接订阅发布的消息:
Payments
订阅OrderCreated
。这种互动方式被称为编舞。这并不一定是坏事,但你必须权衡利弊。例如,当您需要在两者之间添加一个步骤时,您可以让地址
BC订阅创建的订单
,以便它可以验证交付地址。现在,Payments
BC必须订阅addressvalidated
事件。不过,由于我们在注册客户时也会使用它,所以这次活动的发布量很大。嗯
另一种选择是使用编排,在其中显式存储相关流程的状态。您有一个OrderProcess
和一个CustomerOnboardingProcess
。然后,您可以让当前BC仅处理其自己BC中的消息。然后,BC的另一个进程将协调消息并跟踪状态
编舞中可能遇到的另外两个问题是:
- 不得不等待人为干预
- 并行处理,其中两个任务为同一进程运行,一个任务需要将结果重新组合在一起
我希望这是有意义的。也许这是一个不好的例子,但逻辑保持不变,我应该将跨多个BC使用的事件定义放在哪里?如果BC需要侦听事件,它还需要触发它的对象。因此,我不确定您是否需要过于担心模块化,因为您将始终包含引发事件的对象。但我不知道你说的“过去的”是什么意思。你的意思是BC必须能够触发事件还是监听事件?我的意思是OrdersBC必须触发OrderCreated事件,PaymentsBC必须监听它,因此它们确实是因为这个事件而耦合的。正如tomliversidge所说,为OrdersBC.Events创建一个单独的库的想法可能是好的,但我仍然担心模块化。我想在一个基础设施上部署OrdersBC,或者在其他地方部署PaymentsBC,或者根本不部署,但是你应该问问自己:如果PaymentsBC甚至不知道上下文,它怎么知道OrderCreated事件?也许你应该看看两个独立的项目,比如通过套接字进行通信。同样,对PHP不太清楚,但在C#world中,如果你从一个独立的库导入了对dll的引用,你仍然可以部署一些东西。这与导入库来帮助解析JSON是一样的。您只需部署特定的BC代码,外加少量编译代码