“端口—适配器”模式的概念(2)

Mr.Z
Written by Mr.Z on
“端口—适配器”模式的概念(2)

这是“端口—适配器”模式的概念梳理第二部分。

3.- CONFIGURABLE DEPENDENCY PATTERN

配置依赖依赖注入 的一种概括,也被称为控制反转

它是 Gerard Meszaros 起的一个新名称。Alistair Cockburn 认为它是该模式的更好名称,因为它是一种特性,一种特征。“依赖注入”不是属性,它是一个操作,它是你实现配置依赖的一种东西。“控制反转”是一个双重否定,类似于先把事情做错然后反转它们。

“配置依赖”符合模式的定义:

“事物的模式是事物良好范例的共同特征”。

我们可以说配置依赖是对象在接口之上的一种依赖。这个接口将是对象构造器的参数。然后,运行时,在实例化对象的时候,该接口的一个特定实现被传给该构造器。

六边形架构把配置依赖模式应用于驱动者和从动者两侧。在“参与者-应用程序”的交互中,开始对话的一方必须知道另一方,以便了解要跟谁通话,比如,它必须在另一方实现的接口上具有一个配置依赖:

  • 驱动者侧:对话由驱动者(主角参与者)开始,所以驱动者适配器在驱动者端口上有一个配置依赖,其是由应用程序实现的一个接口。
  • 从动者侧:对话由应用程序开始,所以应用程序在从动者端口上有一个配置依赖,其是由配角参与者的从动者适配器实现的一个接口。

所以依赖如下图这样:

20200803ddd-figure5

  • 一个驱动者适配器依赖于六边形(它使用一个驱动者端口的接口)。
  • 一个从动者适配器依赖于六边形(它实现一个从动者端口的接口)。
  • 六边形不依赖任何东西,可能只跟编程语言工具有关。

配置依赖是“端口—适配器”架构所基于的最重要模式,因为它使得六边形与任何技术解耦。而这种解耦使得该架构的主要目标成为可能,就是说,拥有了一个由多个驱动者运行,并能与 recipients/repositories 进行隔离性测试的应用程序。

4.- FROM “SYMMETRICAL ASYMMETRY” TO “ASYMMETRICAL SYMMETRY”(从“对称的不对称”到“不对称的对称”)

听起来相当令人困惑吧?如果是,那就对了,这正是我想要的效果。让我来解释一下。

当该模式被写于 2005 年时,作者想要展示的是传统分层架构的不对称(用户侧 vs 数据侧),实际上是对称的。他通过画出一个六边形并把 UI 和数据库置于外侧来表示这种对称。数据库如同 UI 一样,只是技术,应用程序不了解它,正如同不了解 UI。

通过为其创建一个从动者端口,然后通过创建一个实现该端口的从动者适配器来应用配置依赖模式,把应用程序与数据库解耦。这样数据库依赖于应用程序,而不是其他方式。

然后,当实现六边形架构范例时,作者认识到这种对称实际上是不对称的,因为配置依赖模式在从动者侧和驱动者侧是不同的。

在从动者侧,应用程序必须了解从动者适配器,因为是应用程序开启对话。它必须了解要跟谁对话。

而在另一侧,驱动者侧,是必须了解应用程序的驱动者适配器来开启对话。应用程序不知道是哪一个驱动者来驱动它的。

所以结论是什么?“端口-适配器”对称还是不对称?

其必然结果就是“对称”和“不对称”共存:

  • 对称:所有的适配器,包括驱动者和从动者,都依赖于六边形。在两侧,应用程序都是跟技术无关的。
  • 不对称:配置依赖的实现在每一侧是不同的。在驱动者侧,应用程序不了解是哪个适配器在驱动它。但在从动者侧,应用程序必须了解它要跟哪一个从动者适配器对话。

5.- MISCONCEPTIONS

5.1 - LAYERED ARCHITECTURE

很多我读过的关于该架构的文章都说其是分层的。它们说到了三个层:领域(domain)、端口(ports)、适配器(adapters)。我不知道它们为什么说这些,这个模式没有说到任何分层。该模式只说我们有一个应用程序(六边形),带有给定数量的端口,而对每个端口我们可以有不同的适配器,每个使用一种技术。一个字都没有说到分层。

5.2 - WHY A HEXAGON?

一些人想知道为什么是一个六边形,可能认为边的数量很重要。答案是否定的,根本不用在意这个。六这个数字完全不重要。无论如何,如果你好奇的话,这里有一些 Alistair Cockburn 关于为什么选择六边形的原因:

  • 你有了足够的空间来描绘所需要的端口和适配器。
  • 形状应指示内部/外部的不对称性,而不是顶部/底部或左侧/右侧的。 那么正方形不合适。 五边形,七边形,八边形,……都很难绘制。 因此,六边形赢了。

5.3 - PORTS OUTSIDE ADAPTERS

我看到很多图把端口置于适配器之外,这样参与者就直接与端口进行交互,而适配器就是端口跟六边形之间的中间件了。这种方式:

参与者 ==> 端口 ==> 适配器 ==> 六边形

根本是不正确的。

端口是六边形的边界。实际上,它们属于六边形,是其一部分,是六边形的接口。参与者通过适配器与六边形(的端口)进行交互。适配器是参与者跟端口之间的中间件。正确的描绘是:

参与者 ==> 适配器 ==> (端口)六边形

对于驱动者侧和从动者侧都是如此。这就是“端口-适配器”模式的对称性。

Mr.Z
About Mr.Z A Chinese software engineer living and working in Chengdu. I love Creating the future in digital worlds, big and small.

Comments

comments powered by Disqus