六边形架构

六边形架构围绕 7 个章专属概念,以边界模型、决策轨迹、违规恢复和来源分层完成验收。

学习目标

  • 能解释“六边形架构”如何把应用核心与用户、测试、批处理、数据库和设备隔开,通过端口声明意图、适配器翻译技术协议
  • 能逐项定位 系统内外、端口、适配器、驱动侧、被驱动侧、用户界面与数据库隔离、测试隔离,并说明每个概念在当前来源边界内承担什么责任
  • 能按 识别外部参与者 → 定义输入端口 → 执行应用行为 → 调用输出端口 → 替换适配器测试 推演“无界面验收”,检查“应用可以在没有真实用户界面和数据库时运行,外部技术通过端口接入而不改写内部业务语义”
  • 能注入“把六边形理解为必须存在六条边,或只把 Controller 改名 Adapter 而保留核心对框架的依赖”,依据端口清单、驱动与被驱动方向、适配器合同测试、无 UI 运行、内存存储替换与协议翻译样本定位越界、撤销并用同一情境重放

为什么从“从应用与外部世界的交互意图识别端口,再为每种技术环境实现适配器,并让测试成为一等驱动者”开始

把应用核心与用户、测试、批处理、数据库和设备隔开,通过端口声明意图、适配器翻译技术协议。本页先画责任和依赖,再沿具体情境执行决策,最后主动制造一个边界违规;这种顺序把术语变成可以验证、推翻和恢复的设计合同。

“六边形架构”不是技术采购建议。它处理的是规则放在哪里、模型在哪个语境内成立、哪些变化可以被隔离,以及团队如何判断一条边界已经被穿透。最终功能可运行,只能证明快乐路径存在,不能证明结构允许安全演进。

来源、版次与课程边界

本单元是专题扩展,依据 Alistair Cockburn 2005 年原始 Hexagonal Architecture 文章;六边形只是避免上下分层偏见的视觉约定,不是边数要求。

本专题不是某一本既有书的中文版,也不是把多位作者的文章拼成“原著章节”。课程主干分别取自 Eric Evans 的领域驱动设计体系与 Robert C. Martin 的整洁架构体系;CQRS、事件溯源和六边形架构始终标为扩展。以下链接承担不同事实责任:

本页采用独立中文重写。能从公开全文或授权摘要核对的定义才作为来源事实;项目情境、交互实验、取舍表和练习答案均为本站教学设计。

核心概念与可观察责任

系统内外

六边形架构首先区分应用内部与外部世界,不以传统上下层暗示数据库天然位于业务逻辑之下。 在“无界面验收”中,观察重点是应用可以在没有真实用户界面和数据库时运行,外部技术通过端口接入而不改写内部业务语义。

端口

端口是应用与外部交互的目的性接口,表达一类对话的协议;它属于应用边界,而不是具体技术连接器。 在“存储替换”中,观察重点是端口清单、驱动与被驱动方向、适配器合同测试、无 UI 运行、内存存储替换与协议翻译样本。

适配器

适配器把 Web、命令行、测试、数据库或设备协议转换为端口语言,同一端口可以拥有多个技术实现。 在“无界面验收”中,观察重点是应用可以在没有真实用户界面和数据库时运行,外部技术通过端口接入而不改写内部业务语义。

驱动侧

用户、自动化测试、批处理或其他程序从驱动侧发起应用行为;它们通过输入端口表达意图。 在“存储替换”中,观察重点是端口清单、驱动与被驱动方向、适配器合同测试、无 UI 运行、内存存储替换与协议翻译样本。

被驱动侧

应用通过输出端口请求持久化、通知或外部服务,被驱动适配器完成具体技术操作。 在“无界面验收”中,观察重点是应用可以在没有真实用户界面和数据库时运行,外部技术通过端口接入而不改写内部业务语义。

用户界面与数据库隔离

核心既不从界面控件读取业务输入,也不把数据库结构当领域模型;二者都可以独立更换和自动测试。 在“存储替换”中,观察重点是端口清单、驱动与被驱动方向、适配器合同测试、无 UI 运行、内存存储替换与协议翻译样本。

测试隔离

测试适配器直接驱动端口并用内存适配器接管外部依赖,使应用逻辑在稳定、快速环境中完整运行。 在“无界面验收”中,观察重点是应用可以在没有真实用户界面和数据库时运行,外部技术通过端口接入而不改写内部业务语义。

一条可执行的设计判断

本页采用以下判断链:从应用与外部世界的交互意图识别端口,再为每种技术环境实现适配器,并让测试成为一等驱动者。正常情况下必须持续保持“应用可以在没有真实用户界面和数据库时运行,外部技术通过端口接入而不改写内部业务语义”;反例“把六边形理解为必须存在六条边,或只把 Controller 改名 Adapter 而保留核心对框架的依赖”只改变一个关键条件,便于定位因果。

观察项本页合同
最小正常情境用测试脚本直接提交借书请求并检查结果
边界或迁移情境验收时用内存仓储,生产使用 SQL 仓储
必须保持应用可以在没有真实用户界面和数据库时运行,外部技术通过端口接入而不改写内部业务语义
首要违规把六边形理解为必须存在六条边,或只把 Controller 改名 Adapter 而保留核心对框架的依赖
验收证据端口清单、驱动与被驱动方向、适配器合同测试、无 UI 运行、内存存储替换与协议翻译样本

先预测,再操作三个本页实验

分步1 / 3

实验一:边界与模型地图

操作前先预测“无界面验收”里哪一侧拥有规则、哪一侧只是技术或协作细节。切换概念和情境后,检查“从应用与外部世界的交互意图识别端口,再为每种技术环境实现适配器,并让测试成为一等驱动者”是否仍能解释三块区域的责任。

Boundary model

六边形架构:边界与责任地图

把应用核心与用户、测试、批处理、数据库和设备隔开,通过端口声明意图、适配器翻译技术协议

切换最小情境

定位正式概念

architecturedomaindesign-11 · 当前观察

系统内外用测试脚本直接提交借书请求并检查结果

区域 1驱动适配器

Web、CLI、批处理与自动化测试

区域 2应用与端口

业务用例及输入输出交互意图

区域 3被驱动适配器

数据库、消息、设备与外部服务

情境验收

测试适配器驱动同一输入端口,不复制应用规则

易错边界与取舍

练习与答案

练习

问题 1:概念—边界—证据对照。 完成以下逐项核对:

  1. 系统内外:写出它所在的边界、允许的依赖方向、一个最小反例和一份可观察证据。
  2. 端口:写出它所在的边界、允许的依赖方向、一个最小反例和一份可观察证据。
  3. 适配器:写出它所在的边界、允许的依赖方向、一个最小反例和一份可观察证据。
  4. 驱动侧:写出它所在的边界、允许的依赖方向、一个最小反例和一份可观察证据。
  5. 被驱动侧:写出它所在的边界、允许的依赖方向、一个最小反例和一份可观察证据。
  6. 用户界面与数据库隔离:写出它所在的边界、允许的依赖方向、一个最小反例和一份可观察证据。
  7. 测试隔离:写出它所在的边界、允许的依赖方向、一个最小反例和一份可观察证据。

问题 2:最小情境推演。 怎样验证“无界面验收”没有靠最终功能碰巧通过?

问题 3:替代方案与恢复。 注入“把六边形理解为必须存在六条边,或只把 Controller 改名 Adapter 而保留核心对框架的依赖”后,怎样比较修复与更简单方案?

本页小结

  • 六边形架构的核心判断是:从应用与外部世界的交互意图识别端口,再为每种技术环境实现适配器,并让测试成为一等驱动者。
  • 正常路径以“测试适配器驱动同一输入端口,不复制应用规则”验收,不能只检查接口返回成功。
  • 边界路径以“两个适配器满足同一输出端口合同,应用核心无需分支判断”验收,并保存端口清单、驱动与被驱动方向、适配器合同测试、无 UI 运行、内存存储替换与协议翻译样本。
  • 如果“把六边形理解为必须存在六条边,或只把 Controller 改名 Adapter 而保留核心对框架的依赖”仍可静默通过,说明边界只是图示,没有成为可执行约束。

讨论

评论区加载中…