在不同的软件模块之间共享领域模型。
Sharing a domain model between different software modules.
考虑以下情况。
三个应用程序 A、B 和 C 必须协同工作:A 是外部第三方应用程序,而 B 和 C 是内部应用程序(因此我们控制的是 B 和 C,而不是 A)。 B 使用包含在 C 和 B 本身中的两种逻辑来回复 A 的请求。将 B 视为 A 和 C 之间的层。
A、B 和 C 理解和使用一些基本的共同概念。
假设这里的关键任务是解耦一切,这样如果明天我们想使用 A1 而不是 A,B 和 C 之间的所有交互都保持不变(并且,如果我们想使用 C1 而不是 C , B 和 A 之间的所有相互作用保持不变)。
问题是关于B和C的数据模型设计。我想到了两个解决方案:
- 共享数据模型:我们在不同的项目中引入了一个数据模型D。 D 包含通用概念的 "in house" 版本,供 B 和 C 使用:概念的 A 版本映射到 D 版本,B 和 C 都可以使用和理解。如果明天我们想要使用 A1 而不是 A,我们只需重新编写适配器即可。相反,如果我们想摆脱 C,我们使用通用数据模型 D 编写 C1。
- 复制数据模型:B和C都有自己的数据模型版本。我们现在有两个适配器:一个在 A 和 B 之间,一个在 B 和 C 之间。如果明天我们想要更改 A 或 C,那么我们将重写相应的适配器。
是否有处理这种情况的最佳实践?除了 1. 和 2.,还有其他选择吗? 1. 和 2. 是否存在任何内在问题?
编辑
根据要求,我会尝试给出一个更明确的例子(当然这里的一切都是虚构的。也请原谅我的可怕幻想)。
ACME ltd 是一家二手车零售公司,需要有关每辆已购车和待转售车的详细信息。这个过程是外包的,因此他们公开了一个简单的 DTO,其中包含两个 类 ACME.CarInfoRequest
和 ACME.CarInfoResponse
(包含适当的字段)。特别是有ACME.Car
.
的经营理念
ACME 正在外包给汽车数据提供商 INITECH inc。 INITECH 拥有一个包含汽车信息的大型更新数据库,还具有与警方记录的实时连接,以检查汽车是否被盗。 INITECH 有一个主要应用程序与客户进行交互,并使用不同的应用程序与警方沟通:INIMAIN 应用程序和 INIPOLICE 应用程序。这两个应用程序都具有 "Car" 的基本概念。
问题是:INITECH 应该使用共享数据模型并让 INIMAIN 和 INIPOLICE 将其添加为依赖项还是应该在两个应用程序中实现镜像?
换句话说,这两个解决方案可能是:
1) INITECH 建立INIDATA 项目。 INIDATA包含INIDATA.Car
来表示"car"的概念。 INIMAIN 和 INIPOLICE 都将 INIDATA 添加为依赖项并使用相同的 INIDATA.Car
。当 INIMAIN 和 INIPOLICE 谈到 "Car" 时,不需要翻译(因为它们指的是同一个 INIDATA.Car
)。另一方面,INIMAIN 通过适配器将 ACME.Car
中包含的信息映射到 INIDATA.Car
。
2) INIMAIN 有自己的 INIMAIN.Car
表示(INIPOLICE 分别有 INIPOLICE.Car
)。当 INIMAIN 要 INIPOLICE 询问有关汽车的信息时,首先从 INIMAIN.Car
转换为 INIPOLICE.Car
。然后当 INIPOLICE 回复时,INIMAIN 将所有内容从 INIPOLICE.Car
转换回
INIMAIN.Car
。当然 ACME.Car
仍然通过适配器映射到 INIMAIN.Car
。
希望现在更清楚了(即使这个例子可能很尴尬,再次原谅我的幻想)。
The question is: should INITECH use a shared datamodel and let INIMAIN and INIPOLICE add it as a dependency or should implement mirrors in the two apps
这个问题的答案取决于 INTECH 计划向其客户提供的服务列表。
- 如果访问警察记录是 INTECH 计划为其客户提供的唯一服务,那么
INIMAIN
和 INIPOLICE
模块都是合乎逻辑的共享一个 INDATA.car
域模型(因为只需要支持一个数据模型,即 INPOLICE
将与之对话的外部警察应用程序理解的数据模型)
- 另一方面,如果 INTECH 计划通过与外部保险数据服务对话的
CARINSURANCE
模块提供更多服务,例如汽车的保险详情, INPOLICE
和 CARINSURANCE
模块有自己的数据模型,根据它们与之交谈的外部服务建模(警察记录外部服务和保险记录外部服务通常有自己的请求)会更有意义模型)。在这种情况下,INTECH 应该有 INDATA.PoliceCar
和 INDATA.InsuranceCar
数据模型,INMAIN
会映射 ACME.car
到 INDATA.PoliceCar
或 INDATA.InsuranceCar
取决于 ACME
请求的信息类型
这一切都归结为 INTECH 计划为其客户提供单一服务还是多项服务。如果这在不久的将来很难确定,那么坚持 INPOLICE
和 INMAIN
共享的单一数据模型比为 [=31] 的用例过度设计更有意义=]INTECH可能永远也遇不到。
考虑以下情况。
三个应用程序 A、B 和 C 必须协同工作:A 是外部第三方应用程序,而 B 和 C 是内部应用程序(因此我们控制的是 B 和 C,而不是 A)。 B 使用包含在 C 和 B 本身中的两种逻辑来回复 A 的请求。将 B 视为 A 和 C 之间的层。
A、B 和 C 理解和使用一些基本的共同概念。
假设这里的关键任务是解耦一切,这样如果明天我们想使用 A1 而不是 A,B 和 C 之间的所有交互都保持不变(并且,如果我们想使用 C1 而不是 C , B 和 A 之间的所有相互作用保持不变)。
问题是关于B和C的数据模型设计。我想到了两个解决方案:
- 共享数据模型:我们在不同的项目中引入了一个数据模型D。 D 包含通用概念的 "in house" 版本,供 B 和 C 使用:概念的 A 版本映射到 D 版本,B 和 C 都可以使用和理解。如果明天我们想要使用 A1 而不是 A,我们只需重新编写适配器即可。相反,如果我们想摆脱 C,我们使用通用数据模型 D 编写 C1。
- 复制数据模型:B和C都有自己的数据模型版本。我们现在有两个适配器:一个在 A 和 B 之间,一个在 B 和 C 之间。如果明天我们想要更改 A 或 C,那么我们将重写相应的适配器。
是否有处理这种情况的最佳实践?除了 1. 和 2.,还有其他选择吗? 1. 和 2. 是否存在任何内在问题?
编辑 根据要求,我会尝试给出一个更明确的例子(当然这里的一切都是虚构的。也请原谅我的可怕幻想)。
ACME ltd 是一家二手车零售公司,需要有关每辆已购车和待转售车的详细信息。这个过程是外包的,因此他们公开了一个简单的 DTO,其中包含两个 类 ACME.CarInfoRequest
和 ACME.CarInfoResponse
(包含适当的字段)。特别是有ACME.Car
.
ACME 正在外包给汽车数据提供商 INITECH inc。 INITECH 拥有一个包含汽车信息的大型更新数据库,还具有与警方记录的实时连接,以检查汽车是否被盗。 INITECH 有一个主要应用程序与客户进行交互,并使用不同的应用程序与警方沟通:INIMAIN 应用程序和 INIPOLICE 应用程序。这两个应用程序都具有 "Car" 的基本概念。
问题是:INITECH 应该使用共享数据模型并让 INIMAIN 和 INIPOLICE 将其添加为依赖项还是应该在两个应用程序中实现镜像? 换句话说,这两个解决方案可能是:
1) INITECH 建立INIDATA 项目。 INIDATA包含INIDATA.Car
来表示"car"的概念。 INIMAIN 和 INIPOLICE 都将 INIDATA 添加为依赖项并使用相同的 INIDATA.Car
。当 INIMAIN 和 INIPOLICE 谈到 "Car" 时,不需要翻译(因为它们指的是同一个 INIDATA.Car
)。另一方面,INIMAIN 通过适配器将 ACME.Car
中包含的信息映射到 INIDATA.Car
。
2) INIMAIN 有自己的 INIMAIN.Car
表示(INIPOLICE 分别有 INIPOLICE.Car
)。当 INIMAIN 要 INIPOLICE 询问有关汽车的信息时,首先从 INIMAIN.Car
转换为 INIPOLICE.Car
。然后当 INIPOLICE 回复时,INIMAIN 将所有内容从 INIPOLICE.Car
转换回
INIMAIN.Car
。当然 ACME.Car
仍然通过适配器映射到 INIMAIN.Car
。
希望现在更清楚了(即使这个例子可能很尴尬,再次原谅我的幻想)。
The question is: should INITECH use a shared datamodel and let INIMAIN and INIPOLICE add it as a dependency or should implement mirrors in the two apps
这个问题的答案取决于 INTECH 计划向其客户提供的服务列表。
- 如果访问警察记录是 INTECH 计划为其客户提供的唯一服务,那么
INIMAIN
和INIPOLICE
模块都是合乎逻辑的共享一个INDATA.car
域模型(因为只需要支持一个数据模型,即INPOLICE
将与之对话的外部警察应用程序理解的数据模型) - 另一方面,如果 INTECH 计划通过与外部保险数据服务对话的
CARINSURANCE
模块提供更多服务,例如汽车的保险详情,INPOLICE
和CARINSURANCE
模块有自己的数据模型,根据它们与之交谈的外部服务建模(警察记录外部服务和保险记录外部服务通常有自己的请求)会更有意义模型)。在这种情况下,INTECH 应该有INDATA.PoliceCar
和INDATA.InsuranceCar
数据模型,INMAIN
会映射ACME.car
到INDATA.PoliceCar
或INDATA.InsuranceCar
取决于ACME
请求的信息类型
这一切都归结为 INTECH 计划为其客户提供单一服务还是多项服务。如果这在不久的将来很难确定,那么坚持 INPOLICE
和 INMAIN
共享的单一数据模型比为 [=31] 的用例过度设计更有意义=]INTECH可能永远也遇不到。