
Clean Architecture
by Robert C. Martin · Published 2017
The most systematic treatment of dependency direction and boundaries in software design — the payoff is real, but only for readers who already have Clean Code's discipline in place.
What works
- The Dependency Rule and boundary diagrams give a vocabulary for architecture decisions that otherwise stay implicit
- Framework-agnostic — the ideas outlive any specific stack
What doesn't
- Assumes a level of discipline (and team size) many small projects don't have; over-applying it adds real overhead
- Some of Martin's more dogmatic claims (e.g. on databases as 'details') draw legitimate pushback from practitioners
Summary
Robert C. Martin's argument in Clean Architecture starts from a claim that sounds obvious but that most codebases contradict: the architecture of a software system should tell you what the system does, not what framework it was built with. Open a typical project and the top-level directories announce Rails, or Spring, or Next.js. Martin's position is that this is backwards — the framework is a delivery mechanism, a detail, and letting it occupy the center of the design means the most volatile part of the system is the part everything else depends on.
The book builds toward a single organizing rule, the Dependency Rule: source code dependencies must point only inward, toward higher-level policy. Business rules — the things that would still be true if the application were run by hand on paper — sit at the center and know nothing about the database, the web, or the UI. Those outer layers know about the center. The practical consequence is that you can replace a database or a web framework without touching business logic, because the business logic never imported it in the first place.
Getting there occupies most of the book. Martin works up from programming paradigms (structured, object-oriented, functional, each framed as a restriction on what programmers are allowed to do rather than a new capability), through the SOLID principles at the class level, to component-level principles about cohesion and coupling, before arriving at the architectural layer itself. The through-line is that the same forces operate at every scale, and that architecture is fundamentally about keeping options open — deferring decisions rather than baking them in.
Key ideas
1. The Dependency Rule
The rule is stated in one sentence: source code dependencies must point only inward, toward higher-level policies. Nothing in an inner circle can know anything about anything in an outer circle — not a class name, not a function, not a variable. When an inner layer needs to call outward (business logic needs to save a record), the direction is inverted with an interface: the inner layer defines the interface, the outer layer implements it, and the dependency arrow flips back inward.
The architecture of a software system is the shape given to that system by those who build it. The purpose of that shape is to facilitate the development, deployment, operation, and maintenance of the software system contained within it.
This single rule is what makes the rest of the architecture work. Without it, "layers" are decorative — a project can have a folder called domain that imports the ORM, at which point the domain is not a layer, it's a naming convention.
2. Frameworks, databases, and the web are details
Martin's most contested position is that the database is a detail. His argument is not that databases don't matter operationally, but that from the perspective of business rules, the database is an implementation choice about how records happen to be stored, and business rules that are written against a specific storage mechanism have permanently coupled policy to a decision that should have stayed replaceable.
The same logic applies to the web: HTTP is a delivery mechanism, an I/O device from the application's point of view. If the business rules are written so that a web request is one of several possible ways to invoke them, then the same rules can be driven by a CLI, a queue consumer, or a test harness without modification — which is also, not coincidentally, what makes them testable without spinning up a server.
3. Architecture is about deferring decisions
A recurring theme is that a good architecture maximizes the number of decisions not yet made. Martin argues that the goal of early architecture work isn't to choose the right database or framework quickly — it's to structure the system so those choices can be made late, when there's more information, and changed later if they turn out wrong.
This reframes what "architectural work" means. It's less about picking technologies up front and more about establishing boundaries such that a technology choice, once made, is contained rather than pervasive. A decision that touches one adapter is reversible; the same decision spread across three hundred files is not.
4. Component cohesion and coupling principles
Before the architecture chapters, Martin covers component-level principles that get less attention than SOLID but are arguably more load-bearing at scale. The cohesion principles govern which classes belong in the same deployable component — the Common Closure Principle groups classes that change for the same reasons, while the Reuse/Release Equivalence Principle says the unit of reuse is the unit of release.
The coupling principles then govern dependencies between components: the Acyclic Dependencies Principle (no cycles in the component dependency graph) is the one whose violation is most immediately painful, because a dependency cycle means two components can never be built, tested, or released independently again.
Who it's for
- Developers who have watched a codebase become impossible to change — the book names the specific structural causes rather than blaming discipline.
- Anyone designing a system expected to outlive its current framework — the Dependency Rule is precisely the tool for that.
- Engineers moving from writing features to making architectural decisions — the component principles fill a gap most tutorials skip entirely.
- Teams struggling to test business logic — much of the untestability the book diagnoses comes from policy depending on I/O, which the architecture directly addresses.
FAQ
Do I need to read Clean Code first?
No, they operate at different scales and can be read independently. Clean Code is about functions and classes; this book is about components and boundaries. That said, the discipline Clean Code teaches is assumed here — a codebase with clean architecture and unreadable functions is still hard to work in.
Is this the same thing as hexagonal architecture or ports and adapters?
They're closely related and share the same core insight — Martin explicitly acknowledges Alistair Cockburn's hexagonal architecture, Jeffrey Palermo's onion architecture, and others as expressing the same principle. Clean Architecture is his synthesis of that family, not a competing idea.
Does this apply to frontend work, or only backend?
The principles apply, but the payoff is smaller. A frontend's "business rules" are usually thinner and its framework coupling is much harder to avoid, so full separation often costs more than it returns. The useful part is usually keeping domain logic and data-fetching out of components.
Isn't all this indirection just overengineering?
It can be, and Martin doesn't guard against that as carefully as he should. The honest answer is that the value scales with expected lifespan and rate of change — for a system you'll maintain for years, the boundaries pay for themselves; for a prototype, they're overhead.
What's the book's main weakness?
It doesn't seriously engage with the cost side of its own recommendations. Every boundary, interface and inversion has a real price in indirection and code volume, and the book largely presents the benefits without a comparably rigorous treatment of when the trade isn't worth making.
Was this useful?
Counts appear once there are 5 votes.


