這章整合過去幾十年的系統架構智慧(如 Hexagonal Architecture, Onion Architecture, Screaming Architecture),提出了一個統一的「整潔架構」。
這些架構雖然細節不同,但目標一致:「關注點分離(Separation of Concerns)」

一個整潔系統應具備以下特徵:

  1. 獨立於框架: 架構不依賴於特定程式庫
  2. 可測試: 業務規則可以沒有 UI、資料庫或 Web Server 仍被測試
  3. 獨立於 UI: 可以在不改變業務規則的情況下,將網頁換成 Console 介面
  4. 獨立於資料庫: 可以將 Oracle 換成 Mongo,業務規則不在乎資料如何儲存
  5. 獨立於外部代理: 業務規則對外面世界一無所知。

一、依賴規則 (The Dependency Rule)#

整潔架構由四層同心圓組成。要讓這架構運作,最重要的是:

「原始碼的依賴關係,須只指向內層。」
(Source code dependencies must point only inward, toward higher-level policies.)

  • 內層圓圈中的任何東西,都不知道外層圓圈中的任何東西(包括類別、函數、變數名稱)
  • 外層發生的變化,不應該影響到內層

Figure 22.1: The clean architecture

二、層級介紹 (由內而外)#

層級顏色內容職責特徵
實體層 (Entities)黃色企業級的關鍵業務規則封裝最通用的業務邏輯最不受外部變化影響
使用案例層 (Use Cases)紅色應用程式專屬的業務規則編排與協調實體間的資料流不該受 UI 或資料庫變更影響
介面轉接層 (Interface Adapters)綠色MVC 架構(Controllers, Presenters)資料轉換(內外格式轉換)知道 SQL,但內層完全不知道
框架與驅動層 (Frameworks and Drivers)藍色細節(資料庫、Web 框架、UI)與外部世界溝通只寫膠水程式碼來連接
flowchart TB
    subgraph L4["框架與驅動層 (藍色)"]
        DB[(資料庫)]
        Web[Web 框架]
        UI[UI]
    end
    subgraph L3["介面轉接層 (綠色)"]
        Controller[Controllers]
        Presenter[Presenters]
        Gateway[Gateways]
    end
    subgraph L2["使用案例層 (紅色)"]
        UseCase[Use Cases]
    end
    subgraph L1["實體層 (黃色)"]
        Entity[Entities]
    end

    DB -.-> Gateway
    Web -.-> Controller
    Controller --> UseCase
    Gateway --> UseCase
    UseCase --> Entity
    Presenter --> UseCase

    style L1 fill:#fff3cd
    style L2 fill:#f8d7da
    style L3 fill:#d4edda
    style L4 fill:#cce5ff

三、跨越邊界 (Crossing Boundaries)#

當外層(Controller)想要呼叫內層(Use Case),或者內層(Use Case)想將結果傳給外層(Presenter)時,該怎麼辦?

1. 依賴反向 (DIP)#

根據依賴規則,依賴箭頭只能向內指。但控制流(Control Flow)常常需向外(例如:Use Case 呼叫 Presenter 顯示結果)。

  • 解法: 在內層定義介面(Interface),讓外層去實作它
  • 結果: 控制流向外,但原始碼依賴關係向內(Presenter 依賴 Use Case 的介面)

Figure 22.2: A typical scenario for a web-based Java system

2. 傳遞的資料#

  • 原則: 跨越邊界時,傳遞資料應是簡單、獨立的資料結構(如 DTO, Data Transfer Objects)
  • 禁忌: 千萬不要把「實體(Entity)」或「資料庫的一行(Database Row)」直接傳給外層(如 UI)。
    這會導致內層定義洩漏到外層,或者迫使內層知道外層需求,破壞依賴規則

只要遵守「依賴關係向內」這鐵律,你就能輕易將系統分層,
並獲得一個可測試、可維護、易於更換技術細節的整潔架構。