mcpField
H
hexagonal-architecture-layers-java

hexagonal-architecture-layers-java

github.com/gentleman-programming开发661245 次安装31 周前更新
代码仓库

关于 hexagonal-architecture-layers-java

面向 Java 服务设计与重构的六边形架构 Skill,帮助开发者划分领域、应用和基础设施层,并通过端口与适配器管理依赖方向。

主要功能

  1. 01领域层不依赖框架或 I/O
  2. 02应用层定义用例和端口
  3. 03基础设施适配器实现端口
  4. 04明确依赖方向与模块边界

适用场景

  1. 01设计分层 Java 服务
  2. 02重构 Spring 代码以隔离领域逻辑
  3. 03支持 REST 与消息适配器
  4. 04分离持久化与领域模型

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/gentleman-programming/gentleman-skills --skill hexagonal-architecture-layers-java

安装后在 Claude Code 中输入/hexagonal-architecture-layers-java确认已加载。

详细介绍

适用场景

在以下情况加载此技能:

  • 使用清晰、可测试的分层设计新的 Java 服务
  • 重构 Spring 代码,将领域与框架隔离
  • 支持多个适配器(REST + 消息传递、JPA + Mongo)
  • 强制执行依赖方向和清晰的模块边界

关键模式

模式 1:领域保持纯粹

领域不包含框架注解、持久化相关内容或 I/O。

模式 2:应用层负责编排

应用层定义用例和端口,调用领域逻辑,并将 I/O 委托给端口。

模式 3:基础设施层负责适配

基础设施层实现端口并连接适配器(控制器、存储库、客户端)。

代码示例

示例 1:领域模型 + 输出端口
package com.acme.order.domain;

public record OrderId(String value) { }

public final class Order {
  private final OrderId id;
  private final Money total;

  public Order(OrderId id, Money total) {
    this.id = id;
    this.total = total;
  }

  public OrderId id() { return id; }
  public Money total() { return total; }
}
package com.acme.order.application.port;

import com.acme.order.domain.Order;
import com.acme.order.domain.OrderId;

public interface OrderRepositoryPort {
  OrderId nextId();
  void save(Order order);
}
示例 2:应用用例 + 输入端口
package com.acme.order.application.usecase;

import com.acme.order.application.port.OrderRepositoryPort;
import com.acme.order.domain.Order;
import com.acme.order.domain.OrderId;
import com.acme.order.domain.Money;

public interface PlaceOrderUseCase {
  OrderId place(Money total);
}

public final class PlaceOrderService implements PlaceOrderUseCase {
  private final OrderRepositoryPort repository;

  public PlaceOrderService(OrderRepositoryPort repository) {
    this.repository = repository;
  }

  @Override
  public OrderId place(Money total) {
    OrderId id = repository.nextId();
    Order order = new Order(id, total);
    repository.save(order);
    return id;
  }
}
示例 3:基础设施适配器 + 连接配置
package com.acme.order.infrastructure.persistence;

import com.acme.order.application.port.OrderRepositoryPort;
import com.acme.order.domain.Order;
import com.acme.order.domain.OrderId;
import org.springframework.stereotype.Repository;

@Repository
public final class OrderJpaAdapter implements OrderRepositoryPort {
  private final SpringOrderRepository repository;
  private final OrderMapper mapper;

  public OrderJpaAdapter(SpringOrderRepository repository, OrderMapper mapper) {
    this.repository = repository;
    this.mapper = mapper;
  }

  @Override
  public OrderId nextId() {
    return new OrderId(java.util.UUID.randomUUID().toString());
  }

  @Override
  public void save(Order order) {
    repository.save(mapper.toEntity(order));
  }
}

反模式

不要:在领域中放置框架注解
// BAD: domain tied to JPA
@jakarta.persistence.Entity
public class Order {
  @jakarta.persistence.Id
  private String id;
}
不要:从领域直接调用基础设施
// BAD: domain depends on Spring repository
public class Order {
  private final SpringOrderRepository repository;
}

快速参考

任务模式
持久化领域数据在应用层定义输出端口,在基础设施层实现
暴露用例在应用层定义输入端口和服务
保持领域纯粹不使用注解、I/O 或框架导入

资源

评论

支持 Markdown