Skip to content

Everything Claude Code Hexagonal Architecture Skill 让你在多语言项目中高效落地 Ports & Adapters(六边形架构)模式,实现业务逻辑与框架、数据库、外部 API 的彻底解耦。通过定义清晰的用例边界、依赖倒置和端口适配,本 Skill 支持 TypeScript、Java、Kotlin、Go 等主流服务的可测试、可维护、易扩展架构,适用于新功能开发和遗留系统重构,极大提升 AI 编程助手下的工程质量与协作效率。

Everything Claude Code Hexagonal Architecture Skill:Ports & Adapters、依赖倒置与 UseCase 编排跨语言实现

Hexagonal Architecture Skill 是 Everything Claude Code 插件体系中专为“业务与技术解耦”场景设计的核心能力。它帮助开发者在 TypeScript、Java、Kotlin、Go 等多语言项目中,系统性实现 Ports & Adapters(六边形架构)模式,保证业务规则(Domain)、用例(UseCase)与框架、数据库、外部服务等基础设施彻底分离。无论你是在新项目中追求长期可维护性,还是在重构旧系统时试图消除“耦合地狱”,本 Skill 都能为你提供一套可落地、可测试、可演进的架构实践。

想了解 Everything Claude Code 整体插件体系和 Skill 体系定位,推荐阅读完全指南


1. 这个 Skill 解决什么问题?

在传统项目中,业务逻辑常常直接依赖于 Web 框架、ORM、第三方 SDK 等,导致:

  • 可测试性差:单元测试难以隔离业务,仅能做集成测试。
  • 维护成本高:更换数据库、消息队列或外部 API 时需大规模重写。
  • 多通道适配困难:同一用例无法复用到 HTTP、CLI、定时任务等多入口。
  • 领域边界模糊:业务与技术细节混杂,难以团队协作和演进。

Hexagonal Architecture Skill 通过引导你:

  • 明确划分领域模型、用例、端口(Ports)、适配器(Adapters)和组合根(Composition Root)
  • 所有依赖都“倒置”为接口(Port),业务只依赖抽象
  • 适配器实现接口,基础设施变化时只需替换 Adapter
  • 用例可被多入口(HTTP、CLI、Worker 等)复用
  • 所有边界都可独立单元测试,极大提升质量和信心

2. 触发条件:何时激活 Hexagonal Architecture Skill?

AI 编程助手会在以下场景自动激活本 Skill:

  • 你请求“重构/实现/设计”时,涉及“边界”、“解耦”、“领域驱动”、“依赖倒置”、“多接口适配”等关键词
  • 需要支持同一业务用例被 HTTP、CLI、消息队列、定时任务等多种入口复用
  • 想让业务逻辑独立于数据库、外部 API、消息总线等基础设施
  • 希望为核心用例编写可隔离的单元测试和适配器集成测试
  • 需要迁移遗留系统时,逐步“切片”重构而非大爆炸式重写

3. Step by Step:实际项目中如何用好 Hexagonal Architecture Skill

Step 1:建模用例边界(UseCase)

  • 明确每个业务用例的输入/输出 DTO
  • 不要在 UseCase 层引入 Express req、GraphQL context、消息队列 payload 等协议细节

示例:

typescript
type CreateOrderInput = {
  orderId: string;
  amountCents: number;
};
type CreateOrderOutput = {
  orderId: string;
  authorizationId: string;
};

Step 2:定义所有出站端口(Outbound Ports)

  • 把所有“副作用”依赖(如数据库、支付、日志、时间等)抽象为接口
  • 端口只描述“能力”,不关心技术细节

示例:

typescript
export interface OrderRepositoryPort {
  save(order: Order): Promise<void>;
  findById(orderId: string): Promise<Order | null>;
}
export interface PaymentGatewayPort {
  authorize(input: { orderId: string; amountCents: number }): Promise<{ authorizationId: string }>;
}

Step 3:实现纯净的用例编排

  • UseCase 通过构造函数/参数注入端口
  • 只做业务编排和校验,返回纯数据结构

示例:

typescript
export class CreateOrderUseCase {
  constructor(
    private readonly orderRepository: OrderRepositoryPort,
    private readonly paymentGateway: PaymentGatewayPort
  ) {}
  async execute(input: CreateOrderInput): Promise<CreateOrderOutput> {
    const order = Order.create({ id: input.orderId, amountCents: input.amountCents });
    const auth = await this.paymentGateway.authorize({
      orderId: order.id,
      amountCents: order.amountCents,
    });
    const authorizedOrder = order.markAuthorized(auth.authorizationId);
    await this.orderRepository.save(authorizedOrder);
    return {
      orderId: order.id,
      authorizationId: auth.authorizationId,
    };
  }
}

Step 4:在边界实现适配器(Adapters)

  • 入站 Adapter:将协议输入(HTTP、CLI、消息等)转换为 UseCase 输入
  • 出站 Adapter:将 UseCase 端口映射到具体实现(如 DB、SDK)

示例:

typescript
export class PostgresOrderRepository implements OrderRepositoryPort {
  constructor(private readonly db: SqlClient) {}
  async save(order: Order): Promise<void> {
    await this.db.query(
      "insert into orders (id, amount_cents, status, authorization_id) values ($1, $2, $3, $4)",
      [order.id, order.amountCents, order.status, order.authorizationId]
    );
  }
  async findById(orderId: string): Promise<Order | null> {
    const row = await this.db.oneOrNone("select * from orders where id = $1", [orderId]);
    return row ? Order.rehydrate(row) : null;
  }
}

Step 5:集中组合(Composition Root)

  • 在单一位置(如工厂函数、容器模块)实例化所有 Adapter 并注入 UseCase
  • 禁止全局单例和隐式依赖,方便审计和测试

示例:

typescript
export const buildCreateOrderUseCase = (deps: { db: SqlClient; stripe: StripeClient }) => {
  const orderRepository = new PostgresOrderRepository(deps.db);
  const paymentGateway = new StripePaymentGateway(deps.stripe);
  return new CreateOrderUseCase(orderRepository, paymentGateway);
};

Step 6:按边界测试

  • 用内存 Fake 实现端口,单元测试 UseCase
  • 适配器用集成测试验证与真实基础设施的交互
  • 端到端测试覆盖 Adapter→UseCase→Adapter 全流程

4. 输出示例

预期输出结构:

  • 领域模型、端口接口、用例实现、适配器实现、组合根工厂
  • 每层只依赖抽象,业务与技术彻底分离
  • 可在 TypeScript、Java、Kotlin、Go 等语言平滑迁移

TypeScript 目录结构建议:

text
src/
  features/
    orders/
      domain/
      application/
        ports/
          inbound/
          outbound/
        use-cases/
      adapters/
        inbound/
        outbound/
      composition/

架构图示例:

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"]

5. 常见配套 Agent 与 Skill 协作关系


6. 与其他语言的映射关系

  • TypeScript/JavaScript:接口定义在 application/ports,用例为类/函数,Adapter 明确分层,组合根为显式工厂
  • Java:端口接口在 application.port,用例为普通类,Adapter 分包,组合根可用 Spring 配置或手动 wiring
  • Kotlin:结构与 Java 类似,支持 Koin/Dagger 等依赖注入
  • Go:接口极小,组合根通常在 cmd/main.go,用构造函数显式注入

7. 迁移与重构建议

  • 优先选择变更频繁、影响面小的“纵向切片”逐步迁移
  • 利用“strangler”模式,旧入口逐步路由到新 UseCase
  • 保留旧 Adapter,先让其代理新 UseCase,逐步替换内部实现
  • 所有迁移都要配套行为保持的测试,防止大爆炸式重写

8. 最佳实践与常见陷阱

最佳实践:

  • 领域与用例层只依赖内部类型和端口,无外部依赖
  • 每个外部依赖都抽象为端口接口
  • 校验逻辑分布在 Adapter 边界和 UseCase 层
  • 组合根显式、易于审计
  • 用例可用内存 Fake 单元测试

常见陷阱:

  • 领域模型引入 ORM/SDK/框架类型
  • 用例直接操作 req/res 或数据库行
  • Adapter 之间直接调用,绕过 UseCase
  • 依赖 wiring 分散在多个文件,出现隐式全局单例

FAQ

Q: 这个 Skill 适合哪些项目? A: 适用于需要长期维护、业务复杂、接口多样(如 HTTP、CLI、Worker)的中大型项目,尤其是希望提升可测试性和解耦能力的团队。

Q: 如何让 AI 编程助手自动用上这个 Skill? A: 在需求描述中提及“边界、解耦、依赖倒置、领域驱动、多接口适配”等关键词,或直接请求“按六边形架构实现/重构”,AI 会自动激活本 Skill。

Q: 用六边形架构会不会让项目变复杂? A: 初期结构会比简单脚手架多几层,但带来更强的可维护性、可测试性和适配能力,长期来看复杂度是可控且收益巨大的。