让我们假设系统中有两个域:Orderdomain和Customerdomain。
这两个域都相当复杂和庞大,因此不能将它们合并到一个域中。
但他们之间存在商业关系。在每个订单上,一个客户充当订单员。
我脑子里至少有三个解决方案。
-
将customerId存储为Order和Customer上的基元类型。
-
生成两个值对象OrderDomain.CustomerId和CustomerDomain.Customer Id。请确保可以比较这些类型类型是否相等。
-
使用valeobject CustomerId创建第三个组件"SharedValueObjects",并在两个域中使用该类型
哪一个是首选,或者你能想出一个更好的吗?
我将尝试从您的评论中回答您关于值对象的一般问题和更具体的问题?
- 域可以共享价值对象吗
这取决于情况。在我目前工作的系统中,我们有15个左右的大规模服务,我们共享价值类型,如"EMailAddress"、"PhoneNumber"、"Money"等。这些类型定义明确,我们没有共享问题,但我不会仅仅因为它们可能在其他地方使用而共享,请将您的共享价值类型与实际使用的价值类型进行比较。当共享时,您要付出系统范围耦合的代价。
- 我会将客户和订单之间的关系公开为包装密钥的值对象吗
不,我不会,正如其他人所指出的,客户是在订单领域工作的人会知道并需要数据的东西。如果你声称"客户"one_answers"订单"代表两个不同的域,而不是我假设的"客户"域类似于CRM数据?如果您将"客户"one_answers"订单"分开建模,则"客户"域不能包含您在"订单"域中所需的数据,例如账单地址。我理解您对紧耦合和大型对象图的反对意见,但您可以通过确保系统中允许多个"客户"实体来处理这一问题;每个"客户"在一个有限的上下文中代表其自己的一组数据和行为。例如,您可以在CRM域中同时有一个Customer实体,也可以在"订单"域中有一个Customer实体(我猜它实际上是一个Ordering域,因为"订单"听起来像是一个实体,而不是一组封装的业务流程)。在你的CRM域中,客户可能有一些东西,比如电话号码、联系人、邮政地址等),在"订单"域中,你的客户肯定会有订单,还有账单地址等。所以总结一下:不要创建一个什么都有的客户,把它放在自己的域中,并删除与订单的关系,你只是在缩小对象图的大小。