目录

端口与适配器架构

目录
hexagonal architecture

端口与适配器架构又被称为六边形架构,是一种约定代码设计的架构。它解决的是如何设计代码的问题,主要的关注点在于业务与技术的解耦。

第一次看到这个名字的时候,就有很多问题冒了出来:

  • 它解决什么问题?

  • 什么是端口?什么是适配器?

  • 按照这个架构写出来的代码应该是什么样子?

  • 它为什么又被称作六边形架构?有什么特殊含义?

带着这些问题,搜索了一些资料,算是有了下面的这些理解。

为什么又被称作六边形架构

其实它被称作六边形架构,仅仅是因为它的作者 Dr. Alistair Cockburn 画成这样的而已,没有什么深意。这个架构和“六”这个数字以及“六边形”这个图形都没有任何关联。

那么,这个“六边形”又代表什么呢?

这个“六边形”就是我们所说的“应用”,六边形内的东西,是与技术无关的业务代码。而这些业务代码如何设计,它并没有约定。你可以在内部使用 DDD 战术,也可以使用 “意大利面条式”的代码设计。

一些概念

Actor

Actor 是指那些与应用交互的组件,包括浏览器、命令行甚至其他的应用。所有这些东西都是在我们的“六边形”之外的。

Actor 也有分类,依据是与应用交互的方式:

Drivers

又被称作 Primary Actors。这些 Actor 的特点是它们会调用应用,以完成业务目的。

在画六边形时,Driver 会被画到六边形的左边和上面。

Driven Actors

又被称作 Secondary Actors。这些 Actor 被应用调用,它们提供技术方面的功能以帮助应用完成业务逻辑。

在画六边形时,Driven Actor 会被画到六边形的右边和下边。

Ports

端口处在“六边形”的边缘,用于应用和 Actors 的交互。

根据交互的 Actor 的不同,可以将端口分类为 Driver Port 和 Driven Port ,或者按照《微服务架构设计模式》的说法称作 入站端口 和 出站端口 。

它们被这样分类是因为:

  • 入站端口提供了访问应用的 API

  • 出站端口被应用调用,提供 SPI 供 Driven Actor 实现

端口描述了应用的业务功能,关注点仍然在业务上。

以 Driver Port 来说,可以提供一个 createOrder 端口提供下单的功能。

以 Driven Port 来说,可以提供一个 sendNotification 端口来要求一个发送通知的功能。

但 Actor 并不是直接和端口交互,而是通过 Adapter 来进行的。

Adapters

适配器处在“六边形”之外,所有的 Actor 都是通过适配器来和 Port 交互,以达到和应用交互的效果。

适配器可以根据适配的端口的不同,分为 Driver Adapter 和 Driven Adapter (或 入站适配器 和 出站适配器 )。

适配器就是从“六边形”中解耦出来的“技术”。

以 Driver Adapter 来说,可以实现 REST适配器 来提供 REST 风格的接口来调用端口使用应用;也可以实现 CLI适配器 来提供 CLI 接口来调用端口使用应用。

以 Driven Adapter 来说,可以实现一个 MySQL适配器 以使用 MySQL 持久化数据;也可以实现一个 MongoDB适配器 以使用 MongoDB 持久化数据;也可以实现一个 邮件通知适配器 来实现以邮件形式发送通知的功能。

小结

以上就是端口与适配器架构的核心的概念。

我们可以看到,它的关注点仅仅在于如何将技术代码与业务代码分离开。所以它定义了 Actors、Ports 和 Adapters 这三个概念。而“六边形”并不是一个又特殊含义的东西,只有画出应用的边界和区别 Driver 与 Driven Actor 的作用。

这些概念中,只有 Ports 是属于应用的,其他两个概念都是在应用之外。 - 所有的业务代码,都被包含在了应用之中,而没有被泄漏到应用之外 - 所有需要与第三方交互的技术代码都被放到了 Adapters 里,也就是应用之外,没有侵入到业务代码中

解决的问题

与其他应用交互的代码的设计。

没解决的问题

业务代码怎么写。这需要使用其他的模式来解决,比如 DDD 的战术模式。

如何实现

端口与适配器架构模式要求将应用与适配器分离开,这意味着实现这个模式的时候,需要对应用代码和技术代码做一些技术隔离。 对于 Java 而言,无论是使用 Maven 还是 Gradle 都能比较容易的分离 subproject。其他语言也可以使用类似的技术来实现。虽然不是特别麻烦,但总归是增加了系统的复杂度。

Java 的例子可以参考 这里。

总结

总的来说,端口与适配器模式并不复杂,搞清楚三个关键概念和“六边形”没有意义这个点,就算立即到这个架构模式了。