关于 hexagonal-architecture-layers-java
面向 Java 服务设计与重构的六边形架构 Skill,帮助开发者划分领域、应用和基础设施层,并通过端口与适配器管理依赖方向。
主要功能
- 01领域层不依赖框架或 I/O
- 02应用层定义用例和端口
- 03基础设施适配器实现端口
- 04明确依赖方向与模块边界
适用场景
- 01设计分层 Java 服务
- 02重构 Spring 代码以隔离领域逻辑
- 03支持 REST 与消息适配器
- 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