上下文映射 - 关系
Context mapping - relations
2 个限界上下文可以在它们之间进行上游通信是否被认为是一个坏主意?
例如,订单 BC 将发布事件,库存 BC 将订阅该事件,同时,库存 BC 可以发布事件,订单 BC 将订阅
是的,这是个坏主意。
您的设计会导致两个 BC 之间的循环依赖。与软件开发的许多其他领域一样,循环依赖几乎总是一个坏主意。
如果您的用例迫使您这样做,那么您应该重新考虑您的上下文映射。问自己以下问题:
- 这两个 BC 真的是独立的 BC,还是它们应该是一个?
- 或者导致循环依赖的 BC 之一的一部分实际上应该在第三个 BC 中吗?
在您的域上下文中找到这些问题的答案可能会让您获得更简洁的设计。
不,这不是一个坏主意,事实上这是一个好主意,让我解释一下。
首先考虑你的限界上下文,实际上他们应该对彼此一无所知,即使多个 Contexts
一起工作以创建一个完整的解决方案,所有上下文 knows
都是它自己,它的 OWN 问题。
OnboardingContext
负责公司新员工的入职时间,此处首次将 Employee
实体添加到系统中。此处员工有姓名、电话号码、开始日期、地址、婚姻状况等。
考虑 PayrollContext
,它也有一个 Employee
实体,但这里这个实体只有一个 ID、一个薪水、开始日期和结束日期 - 这里它不关心地址或婚姻状况,它甚至不一定关心姓名,因为在 THIS 上下文中姓名并不重要,只有薪水、开始日期和结束日期。
因此,如果这两个上下文不应该相互了解,但可能关心与两者相关的一些信息,那么我们如何得到一个新的 Employee
已经开始并且需要得到报酬的事实?
域事件
域事件用于分布式系统。该模型当然会变得更复杂,但也更具可扩展性。领域事件用于 event driven architecture
这是它的工作原理
- 新员工启动并在
OnboardingContext
中添加到系统中,一切正常,模型持久化成功。
OnboardingContext
引发了一个事件,这个事件叫做NewEmployeeEvent
OnboardingContext
到此为止。它处理了新员工,保存了它,并引发了一个漂亮的系统范围事件来说明某事(一个事件)已经发生。
现在PayrollContext
PayrollContext
对一些事情感兴趣,特别是它想知道新员工何时开始工作。
- 它订阅了
NewEmployeeEvent
这个事件是一个普通的类型,它不知道这个事件是从哪里来的,实际上它可能来自任何地方,但是它对一个小包感兴趣有关该事件的数据或信息。
- 当事件引发此上下文
handles
那个事件时,在这种情况下会获取有关薪水和员工编号的相关信息,并将其保存到自己的数据存储中,以供以后在工资核算期间使用。
大功告成。
您的系统现在侦听并响应事件,这些事件在您的系统中以任何方向、所有方向流动。
当感兴趣的事情发生并引发事件时,对该事件感兴趣的任何人(上下文)都会订阅、处理并使用与该事件相关的数据做它想做的事情。
那么你是怎么做到的呢?
有很多书要做,只有 google DDD 和领域事件。
你会看到 Jimmy Bogard (a better domain events pattern) and Udi Dahan (Domain Events Salvation) 关于这个主题的很多文章
看看 nservicebus (paid for) and masstransit(开源)它们非常棒,开箱即用的事件和消息传递系统。
Nservice bus 在 https://docs.particular.net/nservicebus/architecture/principles
上有一些关于该主题的精彩视频
2 个限界上下文可以在它们之间进行上游通信是否被认为是一个坏主意?
例如,订单 BC 将发布事件,库存 BC 将订阅该事件,同时,库存 BC 可以发布事件,订单 BC 将订阅
是的,这是个坏主意。
您的设计会导致两个 BC 之间的循环依赖。与软件开发的许多其他领域一样,循环依赖几乎总是一个坏主意。
如果您的用例迫使您这样做,那么您应该重新考虑您的上下文映射。问自己以下问题:
- 这两个 BC 真的是独立的 BC,还是它们应该是一个?
- 或者导致循环依赖的 BC 之一的一部分实际上应该在第三个 BC 中吗?
在您的域上下文中找到这些问题的答案可能会让您获得更简洁的设计。
不,这不是一个坏主意,事实上这是一个好主意,让我解释一下。
首先考虑你的限界上下文,实际上他们应该对彼此一无所知,即使多个 Contexts
一起工作以创建一个完整的解决方案,所有上下文 knows
都是它自己,它的 OWN 问题。
OnboardingContext
负责公司新员工的入职时间,此处首次将 Employee
实体添加到系统中。此处员工有姓名、电话号码、开始日期、地址、婚姻状况等。
考虑 PayrollContext
,它也有一个 Employee
实体,但这里这个实体只有一个 ID、一个薪水、开始日期和结束日期 - 这里它不关心地址或婚姻状况,它甚至不一定关心姓名,因为在 THIS 上下文中姓名并不重要,只有薪水、开始日期和结束日期。
因此,如果这两个上下文不应该相互了解,但可能关心与两者相关的一些信息,那么我们如何得到一个新的 Employee
已经开始并且需要得到报酬的事实?
域事件
域事件用于分布式系统。该模型当然会变得更复杂,但也更具可扩展性。领域事件用于 event driven architecture
这是它的工作原理
- 新员工启动并在
OnboardingContext
中添加到系统中,一切正常,模型持久化成功。 OnboardingContext
引发了一个事件,这个事件叫做NewEmployeeEvent
OnboardingContext
到此为止。它处理了新员工,保存了它,并引发了一个漂亮的系统范围事件来说明某事(一个事件)已经发生。
现在PayrollContext
PayrollContext
对一些事情感兴趣,特别是它想知道新员工何时开始工作。- 它订阅了
NewEmployeeEvent
这个事件是一个普通的类型,它不知道这个事件是从哪里来的,实际上它可能来自任何地方,但是它对一个小包感兴趣有关该事件的数据或信息。 - 当事件引发此上下文
handles
那个事件时,在这种情况下会获取有关薪水和员工编号的相关信息,并将其保存到自己的数据存储中,以供以后在工资核算期间使用。
大功告成。
您的系统现在侦听并响应事件,这些事件在您的系统中以任何方向、所有方向流动。
当感兴趣的事情发生并引发事件时,对该事件感兴趣的任何人(上下文)都会订阅、处理并使用与该事件相关的数据做它想做的事情。
那么你是怎么做到的呢?
有很多书要做,只有 google DDD 和领域事件。
你会看到 Jimmy Bogard (a better domain events pattern) and Udi Dahan (Domain Events Salvation) 关于这个主题的很多文章
看看 nservicebus (paid for) and masstransit(开源)它们非常棒,开箱即用的事件和消息传递系统。
Nservice bus 在 https://docs.particular.net/nservicebus/architecture/principles
上有一些关于该主题的精彩视频