Software Architecture & Design Principles
Architectural Styles
Layered, hexagonal (ports and adapters), and microservices are different granularities of the same underlying move — isolate policy from mechanism — trading simplicity for deployability, and in-process coupling for network coupling.
- Layered: simplest to reason about; risk is layers becoming leaky ("just this once, skip the service layer")
- Hexagonal / ports & adapters: the domain core exposes ports (interfaces); adapters plug in UI, DB, messaging around it — same intent as Clean Architecture Boundaries
- Microservices: independently deployable services, each owning its data; buys team/deployment autonomy, taxes you with distributed-systems problems (network failure, eventual consistency, versioning across services)
- "Monolith first": most systems don't know their true service boundaries on day one — starting modular-monolith and extracting services once boundaries are proven is often cheaper than guessing upfront
- A distributed monolith — services that must deploy together and share a database — has all of microservices' operational cost with none of its independence benefit
| Style | Unit of isolation | Deployability | Main tax |
|---|---|---|---|
| Layered | In-process layer (UI / service / data) | One deployable unit | Layers leak under time pressure |
| Hexagonal | Domain core vs. adapters | One deployable unit (usually) | Discipline to keep the core pure |
| Microservices | Independently deployable service | Each service deploys alone | Network calls, partial failure, data consistency across services |
Hexagonal architecture and Clean Architecture are close cousins: both put the domain model at the center, both forbid it from depending on infrastructure, both use interfaces ("ports" in hexagonal terms) to let infrastructure ("adapters") plug in from the outside. The vocabulary differs; the Dependency Rule (Clean Architecture Boundaries) is the same idea either way.