首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在不复制接口的情况下将monolith分离到域驱动的库中,同时仍然保持依赖关系简单?

如何在不复制接口的情况下将monolith分离到域驱动的库中,同时仍然保持依赖关系简单?
EN

Software Engineering用户
提问于 2016-05-06 17:34:17
回答 3查看 1.6K关注 0票数 6

我正在使用web服务进行一个项目,我一直在构建以下内容:

我最近一直在学习微观服务。事后看来,我希望将服务划分为多个服务,每个服务覆盖业务的特定领域。我该怎么处理图书馆?我在想我可以:

  • 保存所有服务使用的单块库
  • 将库拆分为多个部分(同样,基于业务域)
    • 每个库包含它与之交互的所有接口(这意味着库之间的冗余)。
    • 覆盖两个域之间的空白或边界的胶水库。

我不喜欢单块库,但我无法决定如何处理分裂它。我不喜欢复制模型代码的想法,但我也不喜欢胶水库的想法--这似乎是不直观的,没有它应该的那么简单。

如何在不重复接口的情况下将一元块分离成域驱动的库,并且仍然保持依赖关系简单?

目前,我在想:

  • 包含所有接口和业务逻辑的单个胶水库。
  • 包含实现和数据访问的多个域驱动库
  • 服务主要是从胶水和胶水之间进行翻译。

这是最好的妥协吗?我担心胶水库只是一个微型的单体。

EN

回答 3

Software Engineering用户

回答已采纳

发布于 2016-05-06 18:28:50

在我看来,你的问题分为两部分。第一种方法是围绕接口的重复。第二种是依赖关系。

第一,接口的重复。在您所描述的情况下,您可能希望复制它们。

一个好的经验法则,当打破一个巨石是保持你的边界清楚界定。如果您有两个域,请记住,任何给定域对象都需要以域特有的方式建模,这是违反直觉的。

例如,如果您有一个客户接口ICustomer,并且您有两个域,即订单和发票,尽管订单和发票都使用了某种称为customer的东西,但通常最好是两次定义接口,而不是试图强制使用单个接口(通常是由于对DRY的误解)。这是因为从订单领域的角度来看,客户与发票领域的客户是非常不同的。订单和发票共享相同的ICustomer接口似乎很直观。但事实上,他们可能没有。订单域中的客户与发票域中的客户非常不同,并且由于非常不同的原因会发生变化。

因此,如果您想将项目分成域驱动的微服务,请围绕每个域创建库。不要太担心跨域重用代码(或其他资源)有多好,而是在不破坏无关域中的代码的情况下更改一个域中的代码是多么容易。

第二,依赖关系。这主要是在你解决了上面的问题之后自己解决的。保持依赖关系简单就是将依赖关系保密到其适当的域,然后将用于更广泛依赖关系的接口向下推到基本公共库中。

票数 5
EN

Software Engineering用户

发布于 2016-05-06 17:52:58

我认为您需要依赖反演,其中“更高级”代码(如域)定义了它将与之工作的接口,然后要求使用它的人以某种方式提供合适的实现。

比方说,你雇佣的是一位名流:他们会表演,但他们规定在机场,他们会受到一辆装满薄荷巧克力、瓶装水和小狗的黑色豪华轿车的欢迎。你可能找不到任何豪华轿车服务,糖果店,宠物店,等等,但你肯定可以把它们粘合在一起。(不要让小狗吃巧克力。)

回到现实世界,我现在有一个这样的项目:

  1. 域库
    • 域逻辑
    • 提供像FooRepositoryBarSerializerBulkDataStorer这样的接口。
    • 是针对这些接口编码的,期望使用它的人会注入具体的实现。(在单元测试中,你自己提供。)

  2. 独立的支持图书馆,例如:
    • 一个第三方ORM工具
    • 内部webservice的独立客户端库。
    • 用于web层或MVC的库。

  3. 应用:
    • 把一切都聚集在一起
    • 可能有一个依赖注入框架
    • 提供具体的适配器和外观,以弥合域的接口和能够完成工作的具体类之间的差距。
    • 示例:利用第三方ORM的一个非常薄的FooRepository实现。

现在,如果#3中的任何东西变得太大,您可以选择将它拆分到它自己的库中,但是在我做“胶水库”之前,我要仔细研究它们是否实际上是特定于一个应用程序的上下文,以及它们的可重用性。

票数 2
EN

Software Engineering用户

发布于 2016-05-06 18:21:27

微服务的一个优点是,由于耦合更加松散,每个微服务可以相对独立地发展。

保持单点库及其在所有微服务中的重用不符合逻辑,因为您应该拥有更多的依赖关系。从这种伪微服务方法中获得的唯一优势将是更容易地分发您的服务,因此可能是更好的可伸缩性。

另一个需要考虑的重要问题是,每个微服务都应该是负责自己的数据。拥有大量的微服务( microservices ),使用单个monolith数据库将不知何故错过了重点。这表明什么是对一个微服务的域数据访问,应该是对另一个微服务的域服务请求。

接口的胶水库是进一步解耦服务的第一步。然而,我认为这仍将避免每个微服务的独立发展。我宁愿选择这一选择:

  • 域驱动接口库
  • 微服务的实现,按域划分(不一定在库中),但使用相应的接口库。
  • 域驱动的服务消费库取决于各自的接口库(每个域/微服务的不同库)
  • 使用微服务的应用程序将重用这些服务消耗库,但只重用所需的库。

与glue库相比,这种方法的优点是:

  • 微服务之间的依赖是显式的(消费库的使用),并且减少到了严格的最低限度。
  • 使用者和服务之间的依赖关系在接口库中是隔离的。
票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/317745

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档