Skip to content

Clean Architecture

Clean Architecture

Robert C. Martin’s (Uncle Bob) Clean Architecture

1. Overview of Clean Architecture: A Dependency-Management Architecture That Protects Business Rules from External Technology Change

    flowchart LR
    A["Design coupled to<br/>frameworks, DB, and UI<br/>(technical debt, hard to change)"] --"Dependency Rule:<br/>only inward dependencies allowed"--> B["Concentric-circle layers<br/>(Entity, Use Case,<br/>Interface, Framework)"] --"Independent of<br/>external technology"--> C["A system that is<br/>testable and resilient to change"]

    style A fill:#FFEBEE,stroke:#D32F2F,color:#000
    style B fill:#E3F2FD,stroke:#1976D2,color:#000
    style C fill:#E8F5E9,stroke:#388E3C,color:#000
  

Definition: An architecture proposed by Robert C. Martin whose core principle is the Dependency Rule — “source code dependencies must point only inward, toward policy” — a concentric-circle layered architecture that isolates business rules from external details such as frameworks, databases, and UI.

Characteristics: (Framework independence) Not tied to any specific framework, so business logic is unchanged when swapping Spring for FastAPI. (Testability) Business rules can be tested in isolation without external dependencies. (Independent of UI, DB, and external agencies) The UI (Web→CLI) or DB (MySQL→MongoDB) can be swapped without changing business rules.


2. Core Structure of Clean Architecture

a. The Dependency Rule

    flowchart TD
    subgraph L4["Outer Layer (Frameworks & Drivers)"]
        direction LR
        F1["Web Framework<br/>(Spring, FastAPI)"]
        F2["Database<br/>(MySQL, MongoDB)"]
        F3["External API<br/>(payments, authentication)"]
    end

    subgraph L3["Interface Adapters"]
        direction LR
        A1["Controller<br/>(handles HTTP requests)"]
        A2["Presenter<br/>(formats responses)"]
        A3["Repository Impl<br/>(DB access implementation)"]
    end

    subgraph L2["Application (Use Cases)"]
        UC["Use Case Interactor<br/>(orchestrates business flow)"]
    end

    subgraph L1["Entities (Enterprise Business Rules)"]
        EN["Entity<br/>(core business rules & data)"]
    end

    L4 -->|"Dependency direction<br/>(inward only)"| L3
    L3 --> L2
    L2 --> L1

    style L1 fill:#1E3A5F,stroke:#1E3A5F,color:#fff
    style L2 fill:#E3F2FD,stroke:#1976D2,color:#1E3A5F
    style L3 fill:#F3E5F5,stroke:#7B1FA2,color:#4A148C
    style L4 fill:#f5f5f5,stroke:#ccc,color:#333
  

Core Principles of the Dependency Rule

PrincipleDescriptionViolation Example
Unidirectional dependencyOuter layers may know inner layers, but inner layers must not know outer onesUsing Spring annotations inside an Entity
Dependency Inversion (DIP)Inner layers define only interfaces; outer layers provide the implementationA Use Case depending directly on JpaRepository
Boundary-crossing ruleUse interfaces/DTOs when crossing layer boundariesReturning an Entity directly from a Controller
Data transferUse simple DTOs (Data Transfer Objects) to pass data between layersPassing a DB Entity as-is to outer layers

b. The Entity and Use Case Layers

    flowchart LR
    subgraph ENT["Entity Layer"]
        direction TB
        E1["Enterprise Business Rules<br/>core business concepts & rules<br/>policy unchanged regardless of system"]
        E2["e.g., Order, Product, Payment<br/>holds domain invariants<br/>no dependency on frameworks/DB"]
    end

    subgraph UC["Use Case Layer"]
        direction TB
        U1["Application Business Rules<br/>business flow of a specific application<br/>scenarios that orchestrate Entities"]
        U2["e.g., create order, process payment<br/>defines input→process→output flow<br/>unaffected by UI/DB changes"]
    end

    ENT --> UC

    style ENT fill:#1E3A5F,stroke:#1E3A5F,color:#fff
    style UC  fill:#E3F2FD,stroke:#1976D2,color:#1E3A5F
  
LayerRoleTriggers for ChangeExample
EntityEnterprise-wide business rules — applied identically in any applicationModified only when core business policy changesOrder, Product, maximum order quantity policy
Use CaseOrchestrates the business flow for a specific applicationWhen application behavior changesCreateOrderUseCase, ProcessPaymentUseCase
Interface AdaptersConverts between external formats (HTTP, JSON, SQL) and internal modelsWhen UI/DB technology changesOrderController, OrderRepositoryImpl
Frameworks & DriversDetailed implementation of frameworks, DB, external APIsWhen the technology stack changesSpring Boot, JPA, MySQL, Redis

3. Expected Benefits and Application of Clean Architecture

CategoryExpected BenefitsApplication and Practical Use
TestabilityBusiness logic can be tested standalone without external dependenciesUnit-test the Use Case layer without mocks
Technology independenceBusiness logic unchanged when swapping frameworks or DBPreserves business rules during legacy migration
Linked with MSANaturally combines with service boundaries (DDD Bounded Context)Apply an independent Clean Architecture per microservice
MaintainabilityLimits the blast radius of change to within a layerAdding new requirements touches only outer layers, protecting the core