chapter one

1 Taming complexity with hexagons

 

This chapter covers

  • What hexagonal architecture is and why it matters for maintainable software
  • How it solves the "accidental complexity" problem in growing codebases
  • The core concepts: Ports, adapters, and dependency inversion
  • How hexagonal architecture works

If you’ve ever worked on a codebase that started elegant and ended up an unmaintainable tangle, you already know the villain of this story—where adding a simple feature requires touching dozens of files, where tests break mysteriously after seemingly unrelated changes, where every modification feels like defusing a bomb with garden shears. That creeping rot has a name: accidental complexity. It is the extra mess we introduce through our own design choices, our shortcuts under pressure, our well-intentioned abstractions that calcify into brittle concrete.

The most common source of accidental complexity is not complexity itself, but hard-wiring: components become directly coupled to frameworks, databases, user interfaces, external services, and even to each other’s internal assumptions. Once that happens, every change has somewhere else to travel. A database decision leaks into business logic. A transport model becomes a domain model. A shortcut in one part of the system becomes a constraint somewhere else.

1.1 What is hexagonal architecture

1.1.1 Core concepts: Ports and adapters

1.1.2 The secret sauce: Dependency inversion

1.2 Why hexagonal architecture matters

1.2.1 An uncomfortable truth

1.2.2 The illusion of decoupling

1.2.3 Less of a revelation, more of a confirmation

1.2.4 A pattern that changed everything

1.2.5 Comparison with other patterns

1.2.6 When NOT to use hexagonal architecture

1.3 How hexagonal architecture works

1.3.1 Key Takeaways

1.4 What you need to get started

1.5 How this book teaches hexagonal architecture

1.6 Summary