什么是三位一体架构Trinity Architecture? – Oregor

19-05-03 banq
                   

这里提出的Trinity Architecture是后端企业应用程序的架构模式。它源于采用依赖性倒置原理(DIP)的典型4层架构。它非常适合(但不限于)领域驱动设计(DDD)应用程序。

三位一体的三大支柱是:

  • 所述领域模型(DOMAIN)
  • 公共应用程序编程接口(API)
  • 辅助服务(AUX)

Trinity强调平衡不受控制的灵活性和一致性。它提供了八个顶级模块的具体实施指南。

依赖规则是:

圆圈内的圆圈:外圈取决于内圈。

圆圈外的圆圈:外圆使用(客户端)或实现(细节)内部圆。

Github提供支持工具和库

流行架构模式的简要概述

一开始,当计算机科学出现在50年代/ 60年代时,就没有我们今天所知的架构。开发人员通过优化算法和数据结构来解决问题。

软件架构一词在20世纪90年代初才开始流行。原因是客户端 - 服务器系统的兴起。使用客户端 - 服务器系统,出现了多层体系结构的模式。

后来,在同一个十年中,出现了分层架构。分层的系统将系统分解为逻辑层而不是物理层。

在2000年代,基于依赖性倒置原则出现了新的架构模式。他们的主要目标是解决分层架构的紧耦合问题。

1. 多层架构

有史以来最流行的架构是多层架构。该模式不指定层数,而是一个简单的规则:一层可以与其下面的任何层耦合,但从不与高于它的层耦合。

许多团队可能会争论分层架构中合适的层数。

Martin Fowler(2002)建议三层。(1)表现,(2)领域,和(3)数据源。

Eric Evans(2003)建议四层。(1)用户界面,(2)应用,(3)领域,以及(4)基础设施。

分层架构的好处

  • 简单
  • 一致性
  • 关注点分离

分层架构的缺点

  • 缺乏内置的可扩展性
  • 隐藏的用例
  • 业务逻辑可能从UI扩展到数据库
  • 交换框架和技术很麻烦,如果不是禁止的话
  • 复杂的测试过程
  • 存在太多,不必要的层次的风险

2. 依赖倒置原则

Robert C. Martin 于1996年制定了依赖性倒置原则(DIP)。它代表“ SOLID ”原则中的字母“ D ” 。今天,它是面向对象编程中最着名的原则之一。

DIP的正式定义是:

A.高级模块不应该依赖于低级模块。两者都应该依赖于抽象(接口)。

B.抽象不应该依赖于细节。细节(类)应该取决于抽象。

Vaughn Vernon(2013)演示了如何在典型的4层架构中应用DIP:

通过这种简单的反转,领域层是所有其他层依赖的域层。这种方法消除了与基础设施层的直接耦合。

3基于DIP的架构

在2000年代中期之后,应用程序架构出现了一系列想法。

  • 端口和适配器(六角形),Alistair Cockburn,2005年
  • 洋葱杰弗里巴勒莫,2008年
  • 罗伯特C.马丁的清洁建筑,2012/2017年

虽然它们的细节各不相同,但它们的目标是相同的。它们都旨在通过DIP 更好地分离关注点。我们可以称这个系列的架构模式同心Concentric。

根据Robert C. Martin的说法,他们背后的依赖规则是:

源代码依赖项必须指向内部,指向更高级别的策略。

基于DIP的架构的好处

  • 独立于UI
  • 独立于数据库和其他外部系统
  • 独立于技术特定的库和框架
  • 可互换的基础设施模块
  • 任意数量和类型的客户端
  • 可测试

基于DIP的架构的缺点

  • 复杂
  • 缺少模板(洋葱除外)
  • 前几十年的模糊术语
  • 易受错误依赖和模块结构的影响(如果做得不对)
  • 如何选择模式?

三位一体的形成

Trinity的目标是解决基于DIP的架构的缺点。在本节中,将形成它的形式。所需的步骤是:

  • 从典型的4层开始,定义通用与特定层
  • 定义严格和轻松的依赖关系
  • 应用DIP
  • 包括应用程序模块并构成Trinity体系结构

1.定义通用和特定层

Trinity的起点是典型的4层,正如埃文斯在2003年所提出的那样。当时,诸如REST之类的技术对IT社区来说是未知的。我们现在将术语调整为最新标准:

  1. 客户端、
  2. API、
  3. 领域层
  4. 辅助层

看看上面Vaughn Vernon(2013)转换到这四个层的映射过程:

  • 用户界面层 - >客户端:今天应用程序不仅限于单个用户界面客户端。相反,可以有许多客户端。它们可以存在很多形式(即REST客户端,Web MVC客户端等)
  • 应用层 - >(公共)API:应用层本身不区分公共和内部服务。在这里,我们将它强制为一个特定的层,通过将其重命名为(Public)API来表示其目的。
  • 领域层 - >领域层:领域层是应用程序的核心,已经是一个非常特殊的层,它仍然保持原样。
  • 基础设施层 - >辅助:基础设施可能令人困惑,特别是对于初级开发人员。人们可能只考虑物理服务器,例如数据库或消息服务器。但这不是唯一的例子。例如,基础设施也是实现复杂加密算法的服务。因此,我们用术语辅助替换术语基础设施。辅助程序更好地描述了有助于应用程序目的的任何内容。

2. 定义严格和宽松的依赖关系

在分层体系结构中,层之间有两种类型的耦合:

  • 严格:只允许耦合到它下面的一层。
  • 相关:任何更高级别的层都可以耦合到它下面的任何层。

应用DIP

在下一步中,我们将DIP应用于除了第一个以外下面的所有层,即API客户端。这是最关键的一步。

  • API只定义了DTO的和抽象。
  • Domain领域层定义的模型,它需要所有的抽象。因此,我们删除了与AUX层的耦合。
  • AUX层定义了应用程序所需的DTO和抽象。
  • API细节: 实现的API抽象使用的领域和AUX抽象。
  • DOMAIN详细: 实施的DOMAIN抽象
  • AUX细节: 落实的AUX抽象
  • API客户端使用的API抽象,不是API详细信息。

由于前三个模块仅定义抽象,因此它们与框架无关。

包括应用程序(APP)模块的实战图

接下来,我们包括应用程序模块,它是引导应用程序所必需的。它还负责配置APP,横切关注点等。

通过旋转和重新组织块,我们现在可以形成三位一体架构。

最下面一行是Trinity Core,它们与框架/技术无关。上排是三位一体组合。它提供实现和使用Trinity Core。

另一种观点是圆形的,在文章的顶部描绘。

三位一体架构

1. 核心

三位一体建筑的三大支柱是:

  • 域:域模型
  • API:公共应用程序编程接口
  • AUX:辅助服务

这些模块中的每一个都不依赖于其余任何一个。他们的作用是仅定义DTO,模型和抽象。他们也应该不会有任何关于框架相关的库的依赖关系。唯一可接受的例外是如果需要,使用框架特定注释。

2 API详细信息

该API详细是连接三个独立的组件的API,AUX和DOMAIN的。

它的作用是通过使用Domain和Auxiliary模型以及抽象来实现API。除了特定于框架的注释之外,API Detail仍然是框架不可知的。

3 API客户端

该体系结构支持添加任意数量的API客户端。该API客户端只依赖于抽象API和不域模型或辅助服务。通过这种方式,我们确保每个用例始终都有一个应用程序入口点。

4 AUX详细信息

该AUX细节提供应用程序所需的实现。您应该根据角色将细节分成不同的模块。例如:

  • 文档存储
  • 短信服务
  • SMTP服务
  • 等等

5 域详细信息

该层详细提供了应用程序所需的实现。您应该根据角色将细节分成不同的模块。例如:

  • 持久保存数据库
  • 领域服务
  • 支付网关
  • 模板引擎
  • 等等

6 APP

Bootstraps并配置应用程序。

相关工具和工作

一个三位一体的架构的演示 for Java是可在Github上。

模块的名称与Trinity Architecture图中使用的模块名称相比为1:1。

Java的Trinity Scaffolder

使用Trinity Scaffolder可以用Java生成自己的项目。

trinity4J

trinity4J是一组面向Java应用程序的域驱动设计库。它非常适合Trinity Architecture。

PolyGenesis

Trinity Architecture是一个名为PolyGenesis的更大项目的一部分

PolyGenesis是跨语言自动代码生成的开源平台。它侧重于 DDD和 UI。

结论

​​​​​​​Trinity Architecture的特点是:

  • 清晰的术语和明确定义的模块结构
  • 框架独立核心(API,AUX,DOMAIN)
  • 任意数量的API客户端,域详细信息和辅助详细信息
  • 可互换的技术和框架
  • 可测试
  • 更好地分配团队成员
  • 学习曲线低
  • 支持工具和库

                   

2