軟體系統本質上就是一組 策略(Policy) 集合。
實際上,電腦程式就是對輸入資料轉換並產生輸出的一種詳細描述。

一、策略的重組#

為了建立良好的架構,我們需要將這些策略分解為不同的元件。

  • 原則: 根據 SRP(單一職責原則)CCP(共同封閉原則)
  • 作法: 將那些「為了相同原因而同時變化」的策略,分組在同一個元件中
  • 目標: 將這些元件重組成一個有向無環圖(DAG)

Figure 19.1: A simple encryption program

二、什麼是「層級 (Level)」?#

在架構圖中,我們常說「高層依賴」或「低層實作」,但到底什麼是高低之分?
Uncle Bob 給出一個嚴格定義:

「層級(Level)就是距離輸入與輸出的遠近。」
(Level is strictly defined as the distance from the inputs and outputs.)

  • 低層級(Low Level): 管理輸入與輸出的策略。
    因它們直接接觸 I/O(如讀取 SQL、渲染 HTML),所以距離最近
  • 高層級(High Level): 距離輸入與輸出最遠的策略。
    它們是核心業務邏輯,完全不關心資料從哪讀進來,或顯示到哪去

三、依賴關係的規則#

有了定義,架構規則就非常清晰:「原始碼的依賴關係,應主要指向高層級策略。」

低層級 ➡️ 依賴 ➡️ 高層級

Figure 19.2: Better architecture for the system

為什麼這樣設計?#

這與變化的頻率和原因有關:

  1. 低層級(I/O 相關): 變化非常頻繁(如:更換 UI、升級資料庫驅動、改變報表格式)。
    且變化原因常較瑣碎。
  2. 高層級(業務核心): 變化較少(除非商業模式改變)。變化原因常較為重大。

我們希望「頻繁變化」的組件去依賴「穩定」組件。
讓依賴關係指向高層級(遠離 I/O),就能確保當 UI 或資料庫(低層級)變更時,
核心業務邏輯(高層級)完全不受影響。

Figure 19.3: Lower-level components plug in to higher-level

架構設計的精隨,就是將系統中的策略照「距離 I/O 的遠近」分層,
並嚴格限制依賴方向只能由外(I/O)向內(核心)流動。