在不同领域之间共享值对象是一个好主意吗?

5
假设我们的系统有两个域:Orderdomain和Customerdomain。
这两个域都相当复杂和庞大,因此将它们合并为一个域不是一个选择。
但它们之间存在业务关系。每个订单都由客户作为订购者。
我至少在脑海中有三种解决方案。
1. 在订单和客户上将customerId存储为原始类型。 2. 创建两个值对象OrderDomain.CustomerId和CustomerDomain.CustomerId。确保这些类型可以进行相等比较。 3. 创建一个名为"SharedValueObjects"的第三个组件,其中包含一个值对象CustomerId,并在两个域中使用该类型。
哪一种更好或者你能提出更好的第四种方法吗?

1
看起来当你说“domain”时,你是指实体。问题不够清晰,我认为你把实现细节和概念设计混淆了。如果订单和顾客之间有业务关系,将该关系建模为一等公民。 - JuanZe
不,我指的不是实体或聚合。我指的是不同的领域。但是同样的问题也可以适用于那里,简单的答案是实体肯定可以共享相同的值对象类型。在我看来,你不能仅仅使用一个紧密耦合的领域来建模一个大型业务。仅仅因为实体有某种关系,它们不必成为我的世界中的一流公民。这个领域模型随着时间的推移会变得非常复杂。 - Glenn
2
如何将客户与订单分开?一个没有另一个就没有意义。订单可以存在而没有客户吗?如果不行,那它们怎么可能不在同一领域内呢? - Dan
1个回答

5
我会尝试回答你关于值对象的一般问题以及来自评论中更具体的问题。
1. 领域是否可以共享值对象?
这要视情况而定。在我目前工作的系统中,我们有15个左右的大规模服务,我们共享像“电子邮件地址”、“电话号码”、“货币”等值类型。这些类型定义清晰,我们没有共享问题,但我不会仅仅因为它们可能在其他地方使用而分享一些内容,将共享的值类型留给实际使用的人。在共享时,您要付出整个系统耦合的代价。
2. 是否应该将客户和订单之间的关系作为包装键的值对象公开?
不应该,正如其他人指出的那样,“客户”是在订单领域工作的人会了解并需要数据的内容。如果您声称“客户”和“订单”表示两个不同的领域,那么我假设“客户”领域类似于CRM数据?如果您将“客户”和“订单”建模为两个独立的领域,则“客户”领域不能包含您在“订单”领域中需要的数据,例如账单地址。我理解您反对紧密耦合和巨大的对象图的反对意见,但您可以通过确保允许在系统中使用多个“客户”实体来处理这个问题。每个“客户”表示其自己的数据和行为在一个有界的上下文中。例如,您可以在CRM领域和“订单”领域中都拥有客户实体(我猜它实际上是订购领域,因为“订单”听起来像是一个实体而不是封装的一组业务流程)。在您的CRM领域中,客户可能拥有电话号码、联系人、邮政地址等内容,在“订单”领域中,您的客户肯定会有订单,以及类似账单地址等内容。因此,总结一下:不要创建具有所有内容的客户,将其放在自己的领域中并删除与订单的关系,这样只会减小对象图的大小。

你把两个领域都需要的客户信息,例如“客户姓名”,存放在哪里? - aycanadal
1
客户名称在两个域中是否相同?例如:如果更改客户的名称,以前的订单是否应该反映出更改(如果查看)?我会尝试寻找域之间的差异,并在两个域中建模名称。注意:在报告或视图中使用数据并不表示您需要在两个域中复制数据。这也可能是服务边界不清晰的迹象。 - Marius
如果它是相同的,而且应该在所有地方都进行更改,怎么办?比如修正拼写错误或出于其他原因。 - aycanadal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接