hexagonal-architecture
Official设计、实现并重构端口与适配器系统,具有清晰的领域边界、依赖反转以及跨 TypeScript、Java、Kotlin 和 Go 服务的可测试用例编排。
What this skill does
When applied, it prepends a system prompt before your request is sent — no extra calls and no change to how you are billed beyond the added tokens.
---
name: hexagonal-architecture
description: 设计、实现并重构端口与适配器系统,具有清晰的领域边界、依赖反转以及跨 TypeScript、Java、Kotlin 和 Go 服务的可测试用例编排。
origin: ECC
---
# 六边形架构
六边形架构(端口与适配器)使业务逻辑独立于框架、传输层和持久化细节。核心应用依赖于抽象端口,而适配器在边缘实现这些端口。
## 适用场景
* 构建需要长期可维护性和可测试性的新功能。
* 重构分层或框架密集型代码,其中领域逻辑与I/O关注点混杂。
* 为同一用例支持多种接口(HTTP、CLI、队列工作器、定时任务)。
* 替换基础设施(数据库、外部API、消息总线)而无需重写业务规则。
当需求涉及边界、领域驱动设计、重构紧耦合服务,或将应用逻辑与特定库解耦时,使用此技能。
## 核心概念
* **领域模型**:业务规则和实体/值对象。无框架导入。
* **用例(应用层)**:编排领域行为和工作流步骤。
* **入站端口**:描述应用能力的契约(命令/查询/用例接口)。
* **出站端口**:应用所需依赖的契约(仓库、网关、事件发布器、时钟、UUID等)。
* **适配器**:端口的基础设施和交付实现(HTTP控制器、数据库仓库、队列消费者、SDK封装器)。
* **组合根**:将具体适配器绑定到用例的单一连接位置。
出站端口接口通常位于应用层(仅当抽象真正属于领域层时才位于领域层),而基础设施适配器实现它们。
依赖方向始终向内:
* 适配器 -> 应用/领域
* 应用 -> 端口接口(入站/出站契约)
* 领域 -> 仅领域抽象(无框架或基础设施依赖)
* 领域 -> 无外部依赖
## 工作原理
### 步骤1:建模用例边界
定义具有清晰输入和输出DTO的单个用例。将传输细节(Express `req`、GraphQL `context`、任务负载包装器)保持在此边界之外。
### 步骤2:首先定义出站端口
将每个副作用识别为端口:
* 持久化(`UserRepositoryPort`)
* 外部调用(`BillingGatewayPort`)
* 横切关注点(`LoggerPort`、`ClockPort`)
端口应建模能力,而非技术。
### 步骤3:使用纯编排实现用例
用例类/函数通过构造函数/参数接收端口。它验证应用层不变量,协调领域规则,并返回纯数据结构。
### 步骤4:在边缘构建适配器
* 入站适配器将协议输入转换为用例输入。
* 出站适配器将应用契约映射到具体API/ORM/查询构建器。
* 映射保持在适配器中,而非用例内部。
### 步骤5:在组合根中连接所有组件
实例化适配器,然后将其注入用例。保持此连接集中化,以避免隐藏的服务定位器行为。
### 步骤6:按边界测试
* 使用伪造端口对用例进行单元测试。
* 使用真实基础设施依赖对适配器进行集成测试。
* 通过入站适配器对面向用户的流程进行端到端测试。
## 架构图
```mermaid
flowchart LR
Client["Client (HTTP/CLI/Worker)"] --> InboundAdapter["Inbound Adapter"]
InboundAdapter -->|"calls"| UseCase["UseCase (Application Layer)"]
UseCase -->|"uses"| OutboundPort["OutboundPort (Interface)"]
OutboundAdapter["Outbound Adapter"] -->|"implements"| OutboundPort
OutboundAdapter --> ExternalSystem["DB/API/Queue"]
UseCase --> DomainModel["DomainModel"]
```
## 建议的模块布局
使用以功能为先的组织方式,并带有显式边界:
```text
src/
features/
orders/
domain/
Order.ts
OrderPolicy.ts
application/
ports/
inbound/
CreateOrder.ts
outbound/
OrderRepositoryPort.ts
PaymentGatewayPorUse this skill
Add a "skill" field with the skill’s ID to your chat completion request. It is applied server-side before your prompt is sent — no extra calls.
{
"model": "gpt-4o-mini",
"skill": "imp-16d2e754-2784-4d46-8230-a95dd56f3efb",
"messages": [{ "role": "user", "content": "…" }]
}Install the skill, enable it in your dashboard and (optionally) limit it to specific models. It then applies automatically to every matching request — with no "skill" field to send each time.
Set it up in your dashboardMore skills
Set up and use 1Password CLI for sign-in, desktop integration, and reading or injecting secrets.
Create, view, edit, delete, search, move, or export Apple Notes via the memo CLI on macOS.
List, add, edit, complete, or delete Apple Reminders and reminder lists via remindctl.
Create, search, and manage Bear notes via grizzly CLI.
Monitor blogs and RSS/Atom feeds for updates using the blogwatcher CLI.
BluOS CLI (blu) for discovery, playback, grouping, and volume.
Capture frames or clips from RTSP/ONVIF cameras.
Search, install, update, sync, or publish agent skills with the ClawHub CLI and registry.