Jeffrey Palermo 在 2008 年的部落格文章提出了 Onion Architecture。他觀察到傳統三層架構的問題:Business Layer 依賴 Data Layer,換資料庫要動業務邏輯。他的解法是把依賴方向倒過來——所有層都依賴 domain,沒有任何東西讓 domain 依賴外層。
這個想法比 Uncle Bob 的 Clean Architecture(2012)早,也和 Alistair Cockburn 的 Hexagonal Architecture(2005)同期。三者解決的是同一個問題,Onion Architecture 的貢獻是用「洋蔥切面」的視覺化讓依賴方向變得直觀。
同心圓的結構
Onion Architecture 把系統分成同心圓,從內到外:
┌─────────────────────────┐
│ Infrastructure │
│ ┌───────────────────┐ │
│ │ Application Core │ │
│ │ ┌─────────────┐ │ │
│ │ │Domain Model │ │ │
│ │ └─────────────┘ │ │
│ └───────────────────┘ │
└─────────────────────────┘
Domain Model(最內層):Entity、Value Object、Domain Service、Repository 介面。純粹的業務概念,不依賴任何外部。
Application Core(中層):Application Service(Use Case)、DTO。協調 domain 物件完成業務操作,定義系統對外的能力。
Infrastructure(最外層):資料庫實作、HTTP adapter、外部 API 呼叫。實作 domain 定義的介面,知道所有技術細節。
關鍵規則:依賴只能向內
Onion Architecture 只有一條強制規則:外層可以依賴內層,內層不能依賴外層。
Domain Model 不能 import Application Core 的東西,更不能 import Infrastructure 的任何東西。Application Core 可以依賴 Domain Model,但不能依賴 Infrastructure。Infrastructure 可以依賴任何層。
這條規則讓 domain 可以完全獨立——你可以在不起資料庫、不起 HTTP server 的情況下,把整個 domain model 和 application core 載入記憶體,執行業務邏輯,寫測試。
和 Clean Architecture / Hexagonal 的差別
三者在本質上是同一個想法,主要差異在強調的切面不同:
Onion Architecture 強調同心圓和「依賴向內」的視覺化,對層數的劃分(Domain Model vs Application Core)比 Clean Architecture 更細緻,但沒有明確的「port / adapter」詞彙。
Hexagonal Architecture 強調「port / adapter」的語言和雙向的 port(Driving / Driven),對層數的劃分不如 Onion 細,但在「可插拔的外部介面」這個概念上更清晰。
Clean Architecture 強調同心圓(和 Onion 類似)加上四層的命名,同時借用了 Hexagonal 的依賴倒置概念,是三者中描述最完整的版本,也因此最常被引用。
實務上這三個名字往往指向相同的實作——重要的是理解背後的核心原則(依賴向內),而不是嚴格區分哪個是 Onion、哪個是 Hexagonal。
上一篇 → Hexagonal Architecture
下一篇 → MVVM