Skip to content

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:

java
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).

Built with VitePress | Software Systems Atlas