Domain driven design 上下文映射-关系

Domain driven design 上下文映射-关系,domain-driven-design,microservices,bounded-contexts,Domain Driven Design,Microservices,Bounded Contexts,两个有界上下文之间可以进行上游通信,这被认为是一个坏主意吗 例如,订单BC将发布事件,库存BC将订阅该事件,同时,库存BC可以发布事件,订单BC将订阅是的,这是个坏主意。 您的设计将导致两个BC之间存在循环依赖关系。与软件开发的许多其他领域一样,循环依赖几乎总是一个坏主意 如果您的用例迫使您这样做,那么您应该重新考虑您的上下文映射。问自己以下问题: 这两个BC真的是独立的BC,还是应该是一个 或者,导致循环依赖的某个BC的一部分实际上应该位于第三个BC中吗 在您所在领域的上下文中找到这些问题

两个有界上下文之间可以进行上游通信,这被认为是一个坏主意吗


例如,订单BC将发布事件,库存BC将订阅该事件,同时,库存BC可以发布事件,订单BC将订阅是的,这是个坏主意。

您的设计将导致两个BC之间存在循环依赖关系。与软件开发的许多其他领域一样,循环依赖几乎总是一个坏主意

如果您的用例迫使您这样做,那么您应该重新考虑您的上下文映射。问自己以下问题:

  • 这两个BC真的是独立的BC,还是应该是一个
  • 或者,导致循环依赖的某个BC的一部分实际上应该位于第三个BC中吗
在您所在领域的上下文中找到这些问题的答案可能会引导您进行更干净的设计。

不,这不是一个坏主意,事实上这是一个好主意,让我解释一下。

首先考虑你的有界上下文,在实际情况下,它们不应该互相了解,即使当多个<代码>上下文< /代码>一起工作来创建一个完整的解决方案时,所有的上下文<代码>知道本身就是它自己的问题。 以负责新员工何时进入公司的

OnboardingContext
为例,这里首次将
员工
实体添加到系统中。在这里,员工有姓名、电话号码、开始日期、地址、婚姻状况等

考虑一下
PayrollContext
,它也有一个
Employee
实体,但这个实体只有一个Id、工资、开始日期和结束日期-这里它不关心地址或婚姻状况,甚至不必关心姓名,因为在这个上下文中姓名并不重要,只有工资,开始日期和结束日期

因此,如果这两种情况不应该相互了解,但可能关心与这两种情况相关的一些信息,那么我们如何知道一名新的
员工已经开始工作并需要获得报酬

域事件

域事件用于分布式系统。当然,模型将变得更加复杂,但也更具可扩展性。域事件用于

以下是它的工作原理

  • 新员工启动并添加到系统的
    OnboardingContext
    ,一切正常,模型成功保存
  • OnboardingContext
    引发一个事件,该事件称为
    NewEmployeeEvent
  • 这是关于
    车载上下文的
    ,就它而言,它是完成的。它处理了新员工,保存了它,并引发了一个漂亮的系统范围的事件来表示发生了什么(事件)

    现在转到
    PayrollContext

  • PayrollContext
    对几件事感兴趣,特别是它想知道新员工何时开始工作
  • 它订阅了
    NewEmployeeEvent
    此事件属于常见类型,它不知道事件来自何处,事实上它可能来自任何地方,但它对一小包数据或该事件的信息感兴趣
  • 当引发事件时,此上下文
    处理该事件,在这种情况下,它会获取有关工资和员工编号的相关信息,并将其保存到自己的数据存储中,以供以后在工资发放过程中使用
  • 隆隆声结束了

    您的系统现在会侦听和响应事件,这些事件会在您的系统中以任何方向、所有方向流动

    当感兴趣的事情发生并引发事件时,对该事件感兴趣的任何人(上下文)都会订阅、处理和处理与该事件相关的数据

    那么您是如何做到这一点的?

    有很多阅读要做,只有谷歌DDD和域事件

    你会看到Jimmy Bogard()和Udi Dahan()关于这个主题的许多文章

    看看(付费)和(开源)它们是非常棒的开箱即用事件和消息传递系统


    Nservice bus在

    上有一些关于这个主题的精彩视频,假设我们有订单BC和支付处理BC。创建订单时,将发布事件。然后,事件被缓存并由支付处理微服务/绑定上下文处理。如果处理成功,该订单需要标记为在第一个BC中完成。你想说我应该有第三个microservice/BC,它将存储所有订单及其状态,比如订单历史记录BC?这个具体的例子听起来更像是“将所有东西放在一个BC中”方法的一个例子。但这实际上取决于你的领域是什么样子的,所以我无法给你“正确”的答案。当你与另一个系统集成时,需要你从他们那里接收数据并向他们发送数据,你有某种客户-供应商,通过事件进行双向沟通。我一直担心Eric Evans会说“好吧,这要看情况而定”,会有很多人说不,不要这样做。循环依赖确实是不可取的,但这里的交互是异步的(通过pub-sub)。这种连接器不会产生紧密耦合。出版商和订阅者彼此不了解。因此,出于上述原因,该设计没有问题。事实上,企业集成模式中的Hohpe和Woolf谈到了这一点:请求-应答模式(也称为异步同步)。事件的往返也不会导致任何运行时问题:一个BC main包含多个组件;一个可能包含发送事件的逻辑,另一个可能是使用事件的侦听器。为什么不直接从order BC到inventory BC进行通信,并限制发布/订阅机制的费用