軟體架構就是門「畫線」藝術。 我們在軟體元素間劃出邊界,將其隔離。這些線的目的是為了將「策略(Policy)」與「細節(Details)」分開。
- 策略: 核心業務規則(重要)
- 細節: 資料庫、Web 框架、GUI(相對不重要,只是機制)
一、為什麼要畫線?為了「推遲決定」#
畫線的最主要戰略價值,在於讓我們能 推遲(Defer) 關於細節的決定。
- 過早決定的代價: 許多專案初期就決定我們「要用 MySQL」或「 React」。這時我們對系統需求的了解最少,往往做出次佳選擇
- 架構師的勝利: 一個好架構,能讓你把這些決定推遲到專案的中後期
- 你可以先寫好所有業務邏輯,用「假」資料庫(Mock)測試
- 直到最後,你才需決定真正的資料庫是什麼。這大幅節省了因選錯技術而重構的時間
二、邊界的法則:依賴方向#
這條線該怎麼畫?規則很簡單:將線畫在「重要事物」與「不重要事物」之間。
- GUI vs. 業務規則: 業務規則對 GUI 是什麼一點興趣都沒有。
GUI 不重要(它只是 I/O 通道),業務規則重要 - 資料庫 vs. 業務規則: 資料庫只是儲存資料的工具(細節),業務規則不該知道資料庫的存在

Figure 17.1: The database behind an interface
依賴箭頭的鐵律: 依賴關係的箭頭,必須永遠由「細節」指向「抽象」(由低層級指向高層級)。

Figure 17.2: The boundary line
flowchart LR
GUI[GUI<br/>細節] -->|依賴| BR[業務規則<br/>核心]
DB[(Database<br/>細節)] -->|依賴| BR
style BR fill:#fff3cd,stroke:#856404
style GUI fill:#cce5ff,stroke:#004085
style DB fill:#cce5ff,stroke:#004085
Figure 17.3: The business rules and database components

Figure 17.4: The boundary between GUI and BusinessRules
三、外掛架構 (Plugin Architecture)#
Uncle Bob 在此回顧了軟體開發的歷史,得出了一個結論:
「軟體開發的歷史,就是『如何輕易建立外掛(Plugin)』的歷史。」
- 不對稱關係: 系統元件間的關係是極度不對稱的
- 核心系統(業務規則)對外掛(GUI/DB)免疫
- 外掛對核心系統高度依賴
- 應用: 我們該將 GUI 視為業務規則的 Plugin;將 Database 視為業務規則的 Plugin
- 好處: 既是 Plugin,就意味可插拔(Swappable)。
我們可隨時把 Web 換成 Console GUI,或把 SQL 換成 NoSQL DB,而不影響核心業務邏輯。

Figure 17.5: Plugging in to the business rules

Figure 17.6: ReSharper depends on Visual Studio
架構師的工作是畫出邊界,讓系統的核心邏輯保持純淨。
透過將細節視為外掛,我們不僅保護了核心,更贏得「擁有最多資訊時才決定」的權利。