Comparison
Three answers to three different questions
Hexagonal, Clean Architecture and DDD are almost always presented as competing choices. In reality, they answer different questions and combine naturally in most serious projects.
| Hexagonal | Clean Architecture | DDD | |
|---|---|---|---|
| Author, year | Alistair Cockburn, 2005 | Robert C. Martin, 2012 | Eric Evans, 2003 |
| Question it asks | How do we isolate the business logic from technology? | Which way should dependencies point? | What model belongs in the business logic, and how is it split? |
| Central unit | The domain, at the center of the hexagon | Entities, at the center of the circles | The aggregate, inside a bounded context |
| Boundary vocabulary | Ports (driving / driven) and adapters | Interface adapters, the Dependency Rule | Context mapping (ACL, Shared Kernel, Conformist...) |
| What it guarantees | The business logic tests without a framework or database | No dependency points from inside to outside | The code speaks the same language as the domain experts |
| Weak point if misapplied | Ports that mirror a SQL schema (CRUD in disguise) | Over-layering a trivial app into four circles | Tactical patterns with no Ubiquitous Language or bounded context |
How they fit together
DDD answers the question of content: what should live in the core of the system, and how should it be split into coherent models (bounded contexts)? Hexagonal and Clean Architecture answer the question of structure: once that core is defined, how do we protect it from everything around it?
In practice, DDD's entities and aggregates sit exactly where the hexagonal core or Clean Architecture's "Entities" circle sit. The repositories DDD defines as part of the domain are driven ports in the hexagonal sense. None of these three approaches conflict - they describe the same building from three different angles.
Where to start
Always: the Ubiquitous Language
Talking to the people who use the system and naming the code exactly as they name things costs nothing and prevents most misunderstandings, regardless of project size.
Almost always: ports and adapters
Isolating the business logic behind a few simple interfaces keeps tests fast and makes technology changes less risky, even on a modestly sized application.
Only if the business is genuinely complex: aggregates, multiple bounded contexts
These patterns carry a real design cost. They pay off against authentic business complexity (many rules, strict invariants, multiple teams) - not on a three-screen CRUD app.