Skip to content
José da Cruz

Enterprise Architect, and Life Thinker

José da Cruz

Enterprise Architect, and Life Thinker

Essential Reading: Clean Architecture — Why Dependencies Should Only Point One Way

josedacruz, October 15, 2026October 15, 2026

TL;DR: Robert C. Martin’s “Clean Architecture” argues that the most expensive mistake in software isn’t a bug — it’s letting your business logic get welded to a framework, a database, or a UI you’ll eventually want to rip out. The fix is drawing firm boundaries so the stuff that makes your product valuable doesn’t have to care what database driver you’re using this year.

Cover of Clean Architecture by Robert C. Martin
Cover: Clean Architecture by Robert C. Martin.

The core idea

Martin — widely known by the nickname “Uncle Bob” — spends most of this 2017 book on a single, stubborn question: what should depend on what? His answer is the Dependency Rule: source code dependencies should only point inward, toward your core business rules, and never outward toward details like a web framework, a database, or a UI toolkit. He illustrates this with concentric circles — entities and use cases in the center, interface adapters around them, and frameworks/drivers on the outside — but the diagram is less important than the discipline behind it.

Concretely: imagine a lending library’s “check out a book” rule. That rule — a book can’t be checked out if it’s already checked out, a member can’t have more than five books out at once — is business logic. It should not know or care whether the data lives in PostgreSQL, whether the app is a REST API or a desktop app, or whether you’re using Django or Express this year. If swapping your database requires touching your core business rules, Martin would say your architecture has already failed, even if every test passes.

The practical mechanism for this is the Dependency Inversion Principle (a design rule saying code should depend on abstract interfaces, not on concrete implementations): your business logic defines an interface like BookRepository, and the database-specific code implements it — not the other way around. The business logic never imports a database driver; the database layer imports and implements the business logic’s contract.

Diagram showing the Dependency Rule: Frameworks and Drivers depend on Interface Adapters, which depend on Use Cases, which depend on Entities, with a note that Entities never depend outward

What this means for IT work

This book matters less as a style guide and more as a way to catch a decision while it’s still cheap to undo. The core habit it teaches: before writing code that touches your domain rules, ask “which direction does this dependency point?” If a core class imports a framework annotation, an ORM base class, or an HTTP request object, that’s a dependency pointing the wrong way, and it will cost you later — usually right when you’re under the most pressure to move fast.

A few concrete places this shows up on real teams:

  • The “just add it to the controller” trap: business validation logic creeps into an HTTP handler because it’s the fastest place to add it, until that logic needs to run from a cron job or a CLI tool too, and now it’s duplicated or tangled in web-framework code.
  • ORM-driven domain models: your “Order” class is really just a database row with methods bolted on, so changing how orders are persisted means touching the same class that enforces business rules like “an order can’t ship without payment.”
  • Vendor lock creeping into core logic: a cloud provider’s SDK gets imported directly into business logic instead of behind an interface, and a migration that should take a sprint takes a quarter.
  • Tests that require spinning up a database: if you can’t unit test your core business rules without a running Postgres instance, that’s a visible symptom of the dependency arrows pointing the wrong way.

None of this means rewriting every CRUD app as a hexagon of abstractions. It means noticing, at decision time, when you’re trading a few minutes of indirection now for a painful untangling job later — and making that trade on purpose instead of by accident.

There’s also a quieter payoff that’s easy to miss on a first read: architecture built this way is easier to understand piece by piece. A new engineer can read the use-case layer and learn what the system actually does — check out a book, process a refund, approve a loan — without first learning which web framework or ORM the team picked. The business rules read like the business, not like plumbing. That’s a real productivity win independent of any future migration, because most of the time engineers spend on a codebase isn’t writing new code, it’s figuring out what the existing code is supposed to do.

Where it falls short

The book’s weakest stretch is the long, somewhat dated detour through programming paradigms (structured, object-oriented, functional) early on — it’s a reasonable history lesson but doesn’t add much to the architectural argument, and a reader eager to get to the useful parts can skim it. More substantively, Martin’s examples lean heavily toward the kind of large, long-lived enterprise system he spent his career building, and the book is light on guidance for when this much ceremony is overkill. For a small service with three endpoints and a two-person team, four layers of entities, use cases, and adapters can add more friction than it saves. The useful skill the book teaches — think about dependency direction — scales down just fine; the specific layered structure it recommends does not always need to come along with it.

This book is most worth reading for engineers and architects who’ve felt the specific pain of a “simple” framework or database swap turning into a months-long slog, and want the vocabulary to explain why that happened and how to prevent the next one. It’s less essential for someone building small, short-lived tools where that level of structure would be wasted effort — but even they’ll likely recognize the underlying problem the first time a vendor migration goes sideways.

Related

architecture bookessential-readingsoftware architecturesystems thinking

Post navigation

Previous post

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • architecture (157)
  • artificial-intelligence (6)
  • books (2)
  • courses (4)
  • decision-frameworks (4)
  • finances (1)
  • java (8)
  • life-improvement (20)
  • metrics (3)
  • observability (2)
  • puzzles and challenges (3)
  • reviews (1)
  • security (8)
  • spring-boot (36)
  • Systems Thinking (3)
  • Essential Reading: Clean Architecture — Why Dependencies Should Only Point One Way
  • Essential Reading: Domain-Driven Design — Taming Complexity With a Shared Language
  • GitHub Weekly: 10 Rising Stars You Haven’t Heard Of Yet (October 5 – October 11, 2026)
  • GitHub Weekly: MCP Tools Trending Right Now (September 28 – October 4, 2026)
  • The Bulkhead Pattern: Why One Slow Dependency Shouldn’t Sink the Whole Ship
©2026 José da Cruz | WordPress Theme by SuperbThemes