Metadata Card
- Prerequisites: Chapter 11 (Layered Architecture & MVC)
- Estimated Time: 45 minutes
- Core Difficulty: Advanced
- Completion Milestone: Design hexagonal architecture with clear ports and adapters
Your Progress
Your machine follows City of Artisans standards with four layers. But during maintenance, you find a problem — the core transmission structure has external device interfaces welded directly in: boiler flanges, magic-driven terminal blocks, handle sizes from the control panel.
You want to swap the external engine for a different brand, but the core gearbox bolt positions don't match the new engine — you'd have to redesign the entire core. The core shouldn't depend on peripherals. Your Task
Layered architecture has an inherent tendency: upper layers depend on lower layers, which are typically databases, web frameworks — "external devices." The result: your core business logic is at the bottom of the dependency chain but contaminated by "framework compatibility." Hexagonal Architecture (Ports & Adapters) reverses the dependency direction — core logic is at the center, all external systems interact with the core through ports (interfaces) and adapters (implementations).
Required reading: Hexagonal architecture core concepts, Ports & Adapters Selective: Onion Architecture, Clean Architecture Advanced: DI in hexagonal architecture
First Layer: Ports & Adapters
Core business logic doesn't depend on any framework or external system. Frameworks are "pluggable plugins."
+-------------------------------------------+
| +-----------+ Adapters |
| | Web Adapter| |
| +-----+------+ |
| | |
| +-----------+------------+ |
| | Ports (Interfaces) | |
| | +-------------------+ | |
| | | Core Logic | | |
| | | (No framework deps)| | |
| | +-------------------+ | |
| | Ports (Interfaces) | |
| +-----------+------------+ |
| | |
| +-----+------+ |
| | DB Adapter | |
| | PostgreSQL | |
| +-----------+ |
+-------------------------------------------+Ports — interfaces defining what the core needs. Adapters — implementations. Core knows nothing about adapters.
Testing the core — no app server needed:
class MatchUseCaseTest {
@Test
void finishMatch_savesAndNotifies() {
ForStoringMatches store = new InMemoryMatchStore();
MatchUseCase useCase = new MatchUseCase(store, notifier);
useCase.finishMatch(matchId, winnerId);
assertTrue(store.findById(matchId).orElseThrow().isCompleted());
}
}Second Layer: Onion Architecture — concentric circles, dependencies point inward.
Third Layer: Clean Architecture — same principle by Uncle Bob. Source code dependencies point inward only.
Common Pitfalls: Over-designing for small projects, core layer still depends on framework annotations, ports too fine or too coarse, adapters too thin (don't do I/O in core).
Traveler's Notes
Hexagonal architecture isn't magic — it's simple: wall off the core logic, draw a clear boundary. Inside is "why" (business rules), outside is "how" (technical implementation). Ports are inside requirements; Adapters are outside satisfactions.
Next: Monolith & Microservices Migration (Chapter 13).