The idea
Clean Architecture generalises Hexagonal, Onion and similar styles into one dependency rule: code in an inner circle knows nothing about outer circles. Frameworks, databases and the web are details that sit at the edge.
The four rings
| Ring | Contains | Changes when… |
|---|---|---|
| Entities | Core business objects and invariants | The business itself changes |
| Use cases | One class/function per user intention (AddItemsToRelease) | A workflow changes |
| Interface adapters | Controllers, DTO mappers, repository implementations | The API or storage shape changes |
| Frameworks & drivers | Web framework, DB, UI, queues | You upgrade or swap technology |
Crossing boundaries: when a use case needs to call outward (to save data, say), it calls an interface it owns. The outer ring implements it. This is dependency inversion applied at the architecture level.
- Long-lived products where frameworks will change during the system's life
- Complex workflows you want to unit test by use case
- Large teams that need clear conventions
- Microservices that are basically a DB table with an API
- Hackathons, POCs, throwaway code
Trade-offs
- ✅ The business logic outlives frameworks, and use cases read like documentation.
- ❌ Mapping objects between rings (DTO → entity → persistence model) adds boilerplate.
- ❌ Teams sometimes create four rings for a service with two endpoints. Size the structure to the problem.
Pragmatic version: keep entities + use cases framework-free, and allow a thin "infrastructure" folder to hold everything else. You get most of the benefit at half the ceremony.
Sources & further learning
Videos, courses, docs and books I recommend for this topic.
Related topics
Hexagonal Architecture (Ports & Adapters)
Put the business core at the centre and talk to the outside world — HTTP, DB, queues, third-party APIs — only through ports (interfaces) implemented by swappable adapters.
SOLID Principles
Five object-oriented design principles that keep code open to change — single responsibility, open/closed, Liskov substitution, interface segregation, dependency inversion.
Layered (N-Tier) Architecture
Split an application into horizontal layers — presentation, application, domain, data — where each layer only calls the one below it.