DDD。共享内核?还是纯事件驱动的微服务?
DDD. Shared kernel? Or pure event-driven microservices?
我将我的系统分成(至少)两个限界上下文:研究设计和调查计划。
在研究设计上下文中有一个名为 "subject"(潜在采访对象)的概念。我们还维护该领域中受试者和人群之间的关联。
现在,在调查计划中,我们还需要有关主题的(一些)信息(例如:用于计划访问,甚至用于预期的问卷选择,以防主题所属的人群已知事先)。
所以,我在这两种情况下都需要 "subject"。
我应该选择什么方法?拥有一个共享内核,如 Eric Evans DDD 书中所述?我不介意(至少现在)让两个上下文共享同一个数据库。
或者...我应该使用纯微服务吗?意思是:那两个不能/不应该共享数据库......,在那种情况下,我可能不得不通过事件传递来进行镜像/复制路由:https://www.infoq.com/news/2014/11/sharing-data-bounded-contexts
对于上述情况,有没有想过哪一个更好?
谢谢!
我建议你选择事件驱动的方案,但不一定要使用微服务。您可以构建一个事件驱动的整体,以便花更少的时间同步两个模型。当应用程序变得太大时,您可以将整体拆分为微服务。您可以使用 CQRS 将事件更多的模型拆分为写入和读取。如果您使用事件溯源,事情会变得更加有趣。
根据我的经验,有了共享内核,模型就变成了上帝对象,一刀切的对象。
微服务的上下文是分布式系统。在任何其他情况下,这可能都是矫枉过正。共享内核最终会分裂。通常是这种情况。你可以从它开始。没有错。但是,它不会停留在那里。
在我看来,您拥有三个实体:
- 学习
- 调查
- 人
很直观地看出,每一个都是它自己的聚合根。那么我们正在谈论根间关系。根据我的经验,这些实体本身就是有意义的实体,迄今为止最清晰和最有前途的证据是将这些关系视为独立的聚合根。
研究与人之间的关系可能称为 TestSubject,而人与调查之间的关系可能称为受访者或类似名称。在另一种情况下,这个人可以是公司的雇员,然后雇员将是它自己的聚合根。仅与关系相关而不与个人或研究相关的信息应限于此关系特定的聚合根。例如,这可能是受试者开始参加测试的开始日期,以及结束日期(他退出的时间,如果他或她过早退出等)
至于存储,所有聚合根都应该将自己独立的存储库定义为接口,并且只知道这些接口,但是这些接口的实现可以自由选择使用相同的数据库或不同的数据库,甚至不同的种类,本地或分布式等。所以这也适用于这些 'relational' 聚合根。但是你几乎应该强迫自己使用不同的数据库,甚至最好是不同的技术(例如一个EntityFramework,另一个MongoDb)当你开始这样做时,强迫自己确保你的接口被正确定义和独立于实现。
是的,这里也是 CQRS 的忠实粉丝,Event/Command 采购也是如此。有许多轻量级的实现可能允许您升级,但很容易进入并为您提供几乎完全线性(=可预测)的复杂性。
您可以从共享单一数据源的微服务开始,但只使用部分域实体和值对象
我将我的系统分成(至少)两个限界上下文:研究设计和调查计划。
在研究设计上下文中有一个名为 "subject"(潜在采访对象)的概念。我们还维护该领域中受试者和人群之间的关联。
现在,在调查计划中,我们还需要有关主题的(一些)信息(例如:用于计划访问,甚至用于预期的问卷选择,以防主题所属的人群已知事先)。
所以,我在这两种情况下都需要 "subject"。
我应该选择什么方法?拥有一个共享内核,如 Eric Evans DDD 书中所述?我不介意(至少现在)让两个上下文共享同一个数据库。
或者...我应该使用纯微服务吗?意思是:那两个不能/不应该共享数据库......,在那种情况下,我可能不得不通过事件传递来进行镜像/复制路由:https://www.infoq.com/news/2014/11/sharing-data-bounded-contexts
对于上述情况,有没有想过哪一个更好?
谢谢!
我建议你选择事件驱动的方案,但不一定要使用微服务。您可以构建一个事件驱动的整体,以便花更少的时间同步两个模型。当应用程序变得太大时,您可以将整体拆分为微服务。您可以使用 CQRS 将事件更多的模型拆分为写入和读取。如果您使用事件溯源,事情会变得更加有趣。
根据我的经验,有了共享内核,模型就变成了上帝对象,一刀切的对象。
微服务的上下文是分布式系统。在任何其他情况下,这可能都是矫枉过正。共享内核最终会分裂。通常是这种情况。你可以从它开始。没有错。但是,它不会停留在那里。
在我看来,您拥有三个实体:
- 学习
- 调查
- 人
很直观地看出,每一个都是它自己的聚合根。那么我们正在谈论根间关系。根据我的经验,这些实体本身就是有意义的实体,迄今为止最清晰和最有前途的证据是将这些关系视为独立的聚合根。
研究与人之间的关系可能称为 TestSubject,而人与调查之间的关系可能称为受访者或类似名称。在另一种情况下,这个人可以是公司的雇员,然后雇员将是它自己的聚合根。仅与关系相关而不与个人或研究相关的信息应限于此关系特定的聚合根。例如,这可能是受试者开始参加测试的开始日期,以及结束日期(他退出的时间,如果他或她过早退出等)
至于存储,所有聚合根都应该将自己独立的存储库定义为接口,并且只知道这些接口,但是这些接口的实现可以自由选择使用相同的数据库或不同的数据库,甚至不同的种类,本地或分布式等。所以这也适用于这些 'relational' 聚合根。但是你几乎应该强迫自己使用不同的数据库,甚至最好是不同的技术(例如一个EntityFramework,另一个MongoDb)当你开始这样做时,强迫自己确保你的接口被正确定义和独立于实现。
是的,这里也是 CQRS 的忠实粉丝,Event/Command 采购也是如此。有许多轻量级的实现可能允许您升级,但很容易进入并为您提供几乎完全线性(=可预测)的复杂性。
您可以从共享单一数据源的微服务开始,但只使用部分域实体和值对象