Part 2 · 1 chapters · ~10 min

Clean Architecture

Policy versus detail, the dependency rule, boundaries through dependency inversion, use cases independent of delivery, component cohesion and stability, and frameworks as details, with a TypeScript implementation enforced by lint and an honest note on over-abstraction.

4

Clean Architecture

One rule carries most of the book's value: source dependencies point toward policy. Everything else elaborates on it.

code
// the dependency rule in a TypeScript project: domain knows nothing of the outside
// src/domain/transfer.ts         (policy: no imports from adapters or frameworks)
export interface PaymentProvider { send(t: Transfer, key: string): Promise<ProviderResult> }   // a port
export class InitiateTransfer {
  constructor(private ledger: Ledger, private provider: PaymentProvider, private limits: Limits) {}
  async run(cmd: TransferCommand): Promise<TransferResult> {
    this.limits.check(cmd);                         // pure policy
    const hold = await this.ledger.hold(cmd);       // port
    return this.provider.send(hold.transfer, cmd.idempotencyKey);
  }
}
// src/adapters/paystack.ts       (detail: implements the port)
export class PaystackProvider implements PaymentProvider { /* HTTP, mapping, retries */ }
// src/http/transfers.route.ts    (detail: delivery)
app.post('/transfers', async (req, res) => res.json(await initiateTransfer.run(parse(req.body))));

// .eslintrc: enforce it
// "no-restricted-imports": ["error", { "patterns": [{ "group": ["../adapters/*", "../http/*", "react", "next/*"],
//   "message": "domain must not depend on details" }] }]     (applied to src/domain/**)
where it has aged, and the frontend
The examples are Java-era and the circles can turn into ceremony. Four layers for a form that saves a row is waste. Keep the dependency rule and use as few layers as the domain justifies. On the frontend, the same idea keeps money rules, validation and state machines in plain TypeScript modules (the TypeScript course part 7), with React components only rendering them.
CLEAN ARCHITECTURE
Robert C. Martin, 2017: boundaries and dependency direction
swipe the figure sideways, or tap expand for full screen
1/6
Policy versus detail
Policy and detail: the highest-value code is the policy (business rules, the reason the system exists); everything else (storage, UI, transport, frameworks) is detail. Good architecture keeps options open on details for as long as that is useful.