Loading...
Loading...
Comprehensive guidance for Hexagonal Architecture (Ports & Adapters)—Alistair Cockburn's pattern with a domain core, port definitions, adapter implementations, and complete Java/Spring Boot implementation steps. Covers primary/driving adapters, secondary/driven adapters, use case ports, repository ports, and dependency injection configuration. Use when the user asks about Hexagonal Architecture, Ports and Adapters, Alistair Cockburn, or needs DDD with clean separation.
npx skill4agent add full-stack-skills/ddd-skills ddd-architecture-hexagonal"Allow an application to be equally driven by users, programs, automated tests, or batch scripts, and to be developed and tested in isolation from its final runtime devices and database." — Alistair Cockburn
Boundary validation method: All domain-layer unit tests can pass without a database or HTTP → the boundaries are correct.
ddd-architecture-layeredddd-architecture-coladdd-architecture-cleanDriving Side (REST/CLI/gRPC/Test) → Domain Core ← Driven Side (PostgreSQL/RabbitMQ/Redis/Stripe)| Concept | Description | Code Representation |
|---|---|---|
| Port | An interface defined in the Domain layer | |
| Primary Adapter | How external actors drive the system | REST Controller, CLI Command, gRPC Service |
| Secondary Adapter | How the system drives external systems | JPA RepositoryImpl, Kafka Producer, StripeClient |
// ❌ Weak — 泄漏 SQL 概念
interface OrderRepository { List<Order> findByQuery(String sql, Map<String, Object> params); }
// ✅ Strong — 纯领域概念
interface OrderRepository {
Optional<Order> findById(OrderId id);
List<Order> findByCustomerId(CustomerId customerId);
void save(Order order);
}{project}/
├── {project}-domain/ # 领域核心 + 端口定义(零框架依赖)
│ └── port/{inbound, outbound}/ # ★ 端口接口
├── {project}-application/ # 应用层(UseCase 实现)
├── {project}-adapter/ # 适配器层
│ ├── inbound/ # ★ 主适配器(REST/CLI/gRPC/MQ)
│ └── outbound/ # ★ 次适配器(Persistence/Messaging/External)
└── {project}-configuration/ # 配置层(DI 装配)| Layer | Depends On | Allowed Responsibilities | Prohibited Responsibilities |
|---|---|---|---|
| Domain | None | Entity behavior, value objects, domain events, port definitions | Importing framework annotations, SQL, or HTTP |
| Application | Domain | Use-case orchestration, transaction management, port invocation | if/else business decisions, direct DB operations |
| Adapter | Application | Protocol conversion, parameter validation, exception mapping | Including business logic, directly manipulating internal Domain state |
| Configuration | All | DI wiring, Profile configuration | Including business code |
// 入站端口(Domain)
public interface CreateOrderUseCase { OrderCreatedResult execute(CreateOrderCommand command); }
// 出站端口(Domain)
public interface OrderRepository { void save(Order order); Optional<Order> findById(OrderId id); }
// 应用服务(实现入站端口,注入出站端口)
@ApplicationService
public class CreateOrderService implements CreateOrderUseCase {
private final OrderRepository orderRepository;
@Override @Transactional
public OrderCreatedResult execute(CreateOrderCommand command) {
Order order = Order.create(command.getCustomerId());
orderRepository.save(order);
return OrderCreatedResult.from(order);
}
}
// 主适配器(仅协议转换)
@RestController
public class OrderController {
@PostMapping("/orders")
public ResponseEntity<CreateOrderResponse> create(@RequestBody @Valid CreateOrderRequest req) {
var result = createOrderUseCase.execute(req.toCommand());
return ResponseEntity.status(201).body(CreateOrderResponse.from(result));
}
}
// 次适配器(技术实现)
@Repository
public class PostgresOrderRepository implements OrderRepository {
@Override public void save(Order order) { jpaRepo.save(mapper.toPO(order)); }
}Phase 1: 定义端口(1-2 天)→ 入站端口(UseCase) → 出站端口(Repository/Gateway)
Phase 2: 领域模型(2-3 天)→ 聚合根/实体/值对象 → 领域服务 → 领域事件
Phase 3: 应用服务(1-2 天)→ UseCase 实现(注入端口,编排调用)
Phase 4: 适配器(2-4 天) → 主适配器(REST/gRPC/CLI) → 次适配器(DB/MQ/External)
Phase 5: DI 装配 + 测试(1-2 天)→ DI 配置 → 端口 Mock 测试 → 适配器集成测试CreateOrderUseCaseOrderRepositorysavefindByIdOrderRepositoryQueryOrderUseCase| File | Purpose |
|---|---|
| references/01-port-definitions.md | Port definition standards — inbound/outbound ports, naming, granularity, Strong/Weak |
| references/02-primary-adapters.md | Primary Adapter details — four adapter implementations: REST/CLI/gRPC/MQ |
| references/03-secondary-adapters.md | Secondary Adapter details — JPA/MyBatis/Stripe/RabbitMQ/InMemory |
| references/04-domain-model.md | Domain model design — aggregate roots, entities, value objects, domain services, domain events |
| references/05-application-services.md | Application service layer — UseCase implementation, orchestration standards, command objects |
| references/06-di-configuration.md | DI configuration — Spring Config, Profile switching, multi-environment adapters |
| references/07-testing.md | Testing strategy — four testing levels: domain/application/adapter/architecture |
| references/08-migration.md | Progressive migration — migration guide from traditional three-tier architecture to Hexagonal Architecture |
| examples/01-order-hexagonal-complete.md | Complete order Hexagonal example — end-to-end Domain/Port/Service/Adapter flow |
| examples/02-user-registration-example.md | User registration example — value objects, verification codes, domain events |
| examples/03-multi-entry-points-example.md | Multi-entry-point system example — the same UseCase invoked by REST/CLI/Kafka/gRPC |
| examples/04-adapter-swapping-example.md | Adapter swappability example — Postgres→MongoDB and Stripe→PayPal with no code changes |
| examples/05-port-swapping-test.md | Primary Adapter swappability example — three entry types: REST/gRPC/CLI, plus port-level testing |
| examples/06-monolith-simple.md | Simple monolith in Hexagonal style — four packages in one module, with ports/adapters subpackages |
| examples/07-monolith-complex.md | Complex monolith in Hexagonal style — multiple ports, adapters, and aggregate roots |
| examples/08-monolith-multi-module.md | Monolith with multiple modules — Maven multi-module compile-time boundary constraints |
| examples/09-microservice-simple.md | Simple microservice in Hexagonal style — minimal Hexagonal structure within one microservice |
| examples/10-microservice-complex.md | Complex microservice in Hexagonal style — multiple aggregates, Saga, and cross-service calls |
| examples/11-microservice-multi-module.md | Microservice with multiple modules — Maven multi-module setup within each service |
| examples/12-microservice-complex-multi.md | Complex microservice with multiple modules — CQRS, read/write separation, CDC, and distributed Saga |
ddd-domain-designernpx skills add full-stack-skills/ddd-skills --skill ddd-domain-designerddd-testing-strategistnpx skills add full-stack-skills/ddd-skills --skill ddd-testing-strategistddd-api-designernpx skills add full-stack-skills/ddd-skills --skill ddd-api-designer💡 Hexagonal Architecture = Ports + Adapters. Validation method: Run business logic through CLI/unit tests without starting a database or HTTP server → the boundaries are correct.