“端口—适配器”模式的概念(2)
Summary
这是“端口—适配器”模式的概念梳理第二部分。
3.- CONFIGURABLE DEPENDENCY PATTERN
它是 Gerard Meszaros 起的一个新名称。Alistair Cockburn 认为它是该模式的更好名称,因为它是一种特性,一种特征。“依赖注入”不是属性,它是一个操作,它是你实现配置依赖的一种东西。“控制反转”是一个双重否定,类似于先把事情做错然后反转它们。
“配置依赖”符合模式的定义:
“事物的模式是事物良好范例的共同特征”。
我们可以说配置依赖是对象在接口之上的一种依赖。这个接口将是对象构造器的参数。然后,运行时,在实例化对象的时候,该接口的一个特定实现被传给该构造器。
六边形架构把配置依赖模式应用于驱动者和从动者两侧。在“参与者-应用程序”的交互中,开始对话的一方必须知道另一方,以便了解要跟谁通话,比如,它必须在另一方实现的接口上具有一个配置依赖:
- 驱动者侧:对话由驱动者(主角参与者)开始,所以驱动者适配器在驱动者端口上有一个配置依赖,其是由应用程序实现的一个接口。
- 从动者侧:对话由应用程序开始,所以应用程序在从动者端口上有一个配置依赖,其是由配角参与者的从动者适配器实现的一个接口。
所以依赖如下图这样:
- 一个驱动者适配器依赖于六边形(它使用一个驱动者端口的接口)。
- 一个从动者适配器依赖于六边形(它实现一个从动者端口的接口)。
- 六边形不依赖任何东西,可能只跟编程语言工具有关。
配置依赖是“端口—适配器”架构所基于的最重要模式,因为它使得六边形与任何技术解耦。而这种解耦使得该架构的主要目标成为可能,就是说,拥有了一个由多个驱动者运行,并能与 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
我看到很多图把端口置于适配器之外,这样参与者就直接与端口进行交互,而适配器就是端口跟六边形之间的中间件了。这种方式:
参与者 ==> 端口 ==> 适配器 ==> 六边形
根本是不正确的。
端口是六边形的边界。实际上,它们属于六边形,是其一部分,是六边形的接口。参与者通过适配器与六边形(的端口)进行交互。适配器是参与者跟端口之间的中间件。正确的描绘是:
参与者 ==> 适配器 ==> (端口)六边形
对于驱动者侧和从动者侧都是如此。这就是“端口-适配器”模式的对称性。