【问题标题】:Sharing a domain model between different software modules.在不同的软件模块之间共享域模型。
【发布时间】:2018-02-10 09:28:37
【问题描述】:

考虑以下情况。

三个应用 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 的数据模型设计。我想到了两个解决方案:

  1. 共享数据模型:我们在不同的项目中引入了数据模型 D。 D 包含通用概念的“内部”版本,由 B 和 C 使用:概念的 A 版本映射到 D 版本,B 和 C 都可以使用和理解。如果明天我们想要要使用 A1 代替 A,我们只需重新编写适配器。相反,如果我们想摆脱 C,我们使用通用数据模型 D 编写 C1。
  2. 复制数据模型:B 和 C 都有自己的数据模型版本。我们现在有两个适配器:一个在 A 和 B 之间,一个在 B 和 C 之间。如果明天我们要更改 A 或 C,那么我们重写相应的适配器。

有处理这种情况的最佳做法吗? 1. 和 2. 有什么替代方案吗? 1. 和 2. 是否存在任何内在问题?

编辑 根据要求,我将尝试举一个更明确的例子(当然这里的一切都是虚构的。也请原谅我可怕的幻想)。

ACME ltd 是一家二手车零售公司,需要有关每辆购买和待转售的汽车的详细信息。此过程是外包的,因此他们公开了一个简单的 DTO,其中包含两个类 ACME.CarInfoRequestACME.CarInfoResponse(包含适当的字段)。尤其是ACME.Car的经营理念。

ACME 将外包给汽车数据提供商 INITECH inc。 INITECH 拥有一个包含汽车信息的大型更新数据库,并且还具有与警察记录的实时连接,以检查汽车是否被盗。 INITECH 有一个与客户交互的主要应用程序,并使用不同的应用程序与警察沟通:INIMAIN 应用程序和 INIPOLICE 应用程序。这两个应用程序都有“汽车”的基本概念。

问题是:INITECH 应该使用共享数据模型并让 INIMAIN 和 INIPOLICE 将其添加为依赖项,还是应该在两个应用程序中实现镜像? 换句话说,这两种解决方案可能是:

1) INITECH 构建 INIDATA 项目。 INIDATA 包含INIDATA.Car 代表“汽车”的概念。 INIMAIN 和 INIPOLICE 都将 INIDATA 添加为依赖项并使用相同的 INIDATA.Car。当 INIMAIN 和 INIPOLICE 谈论“汽车”时,不需要翻译(因为它们都指的是同一个 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

希望现在更清楚(即使这个例子可能很尴尬,再次原谅我有限的幻想)。

【问题讨论】:

  • 您的问题有多种解释。如果您提供一个更具体的示例而不是使用诸如AA1BB 等名称,将会有所帮助。
  • @CKing 当然,会尽快编辑问题

标签: design-patterns software-design datamodel design-principles


【解决方案1】:

问题是:INITECH 应该使用共享数据模型并让 INIMAIN 和 INIPOLICE 将其添加为依赖项,还是应该在两个应用程序中实现镜像

这个问题的答案取决于INTECH 计划为其客户提供的服务列表。

  1. 如果访问警察记录是 INTECH 计划为其客户提供的唯一服务,那么 INIMAININIPOLICE 模块共享一个 INDATA.car 域模型是合乎逻辑的(因为只需要支持一种数据模型,即INPOLICE 将与之对话的外部警察应用程序所理解的数据模型)
  2. 另一方面,如果 INTECH 计划通过与外部保险数据服务对话的CARINSURANCE 模块提供更多服务,例如汽车的保险详细信息,那么@ 987654326@ 和CARINSURANCE 模块有自己的数据模型,这些模型根据它们所接触的外部服务进行建模(警察记录外部服务和保险记录外部服务通常有自己的请求模型)。在这种情况下,INTECH 应该有 INDATA.PoliceCarINDATA.InsuranceCar 数据模型,INMAIN 将映射ACME.carINDATA.PoliceCarINDATA.InsuranceCar,具体取决于请求的信息类型由ACME

这一切都归结为 INTECH 计划为其客户提供单一服务还是多种服务。如果这在不久的将来难以确定,那么坚持使用 INPOLICEINMAIN 共享的单一数据模型而不是针对 INTECH的用例进行过度设计会更有意义> 可能永远不会遇到。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多