把三個維度連起來#

Part II 把耦合拆成三個維度,但每一個都不是「最重要的」。它們必須一起被考量、一起被管理。本章把三者整合起來,正式提出 balanced coupling 模型。

設計 cross-component 互動時,目標不是「最小化耦合強度」——歷史上耦合常與 strength 綁在一起,但追求 connascence of name 這種極端弱耦合既不可行也不必要。

真正的目標是:設計出模組化系統——容易實作、容易演進、容易維護。Eric Evans 早就提醒過:不是所有元件都需要被精心設計(核心子領域 vs 支援子領域)。實效需要健康的務實。

概念回顧#

開始合併之前,把核心觀念複習一遍:

  • 知識流向跟依賴方向相反Module A → Module B,B 是上游,知識從 B 流向 A

Figure 10.1: 知識流向與依賴方向相反

  • 整合介面四種類型
    • Intrusive:洩漏所有實作細節
    • Functional:共享業務功能
    • Model:共享業務領域模型
    • Contract:用為整合而生的契約最小化暴露
  • 距離:跨方法 → 跨服務 → 跨系統,距離越遠變更成本越高
  • 易變性:上游模組變動的頻率,決定了「實際付出多少代價」

衡量單位:用二進位開始#

整合強度、距離、易變性各自衡量不同面向,要怎麼放在同一把尺上?本章先用最簡單的二進位:high (1) / low (0),方便用布林邏輯描述各種組合。本章後段會討論數值化的近似做法。

兩兩組合的洞見#

穩定性 = 易變性 × 強度#

STABILITY = NOT (VOLATILITY AND STRENGTH)
VolatilityStrength結果
LowLow/High穩定(低易變性壓制強度)
HighLow穩定(低強度阻擋連動)
HighHigh不穩定

變更成本 = 易變性 × 距離#

CHANGES COST = VOLATILITY AND DISTANCE
VolatilityDistance結果
LowLow/High低(少有變更發生)
HighLow低(變更也容易擴散到附近)
HighHigh

模組化 vs 複雜度 = 強度 × 距離#

最有趣的組合:

StrengthDistance結果
LowLowLocal complexity(不相關元件擠在一起)
LowHighLoose coupling(鬆耦合,標準理想狀態)
HighLowHigh cohesion(同生共死的元件放在一起)
HighHighGlobal complexity(共享變更要橫跨大距離)
MODULARITY      = STRENGTH XOR DISTANCE
COMPLEXITY      = NOT MODULARITY = NOT (STRENGTH XOR DISTANCE)
LOCAL COMPLEXITY  = NOT STRENGTH AND NOT DISTANCE
GLOBAL COMPLEXITY = STRENGTH AND DISTANCE

強度與距離反向時,設計傾向模組化;同向時,設計傾向複雜化。 這把 Part I 的結論「設計一定會把系統推向模組或複雜」具象化。

維護成本:三維乘積#

MAINTENANCE EFFORT = STRENGTH * DISTANCE * VOLATILITY

只要任一維度為 0,痛苦就被中和:

  • Low strength + High distance + High volatility → loose coupling,變更不擴散
  • High strength + Low distance + High volatility → high cohesion,變更擴散但近在咫尺
  • High strength + High distance + Low volatility → 例如整合 legacy 系統,雖耦合很糟,但 legacy 不再演進,整合得以穩定

這個式子有個盲點:Low strength + Low distance + High volatility。本身對「兩個元件」維護成本低,但對它們所在的母模組造成 local complexity——上游一變,工程師得在一堆無關的鄰居中找出真正要改的那個。

Balanced Coupling 公式#

把上述盲點納入:

BALANCE = NOT (COMPLEXITY AND VOLATILITY)
        = MODULARITY OR NOT VOLATILITY
        = (STRENGTH XOR DISTANCE) OR NOT VOLATILITY
StrengthDistanceVolatilityBalance
LowLowLowHigh
LowLowHighLow
LowHigh*High
HighLow*High
HighHighLowHigh
HighHighHighLow

兩種 balance 為 low 的情境共通:複雜度 + 高易變性。一個是 global complexity 加上 high volatility,另一個是 local complexity 加上 high volatility。

數值化版本#

THIS IS NOT AN EXACT SCIENCE. 三個維度本就是主觀的——複雜度會隨觀察層級轉換、模組是階層化的、整合強度也可在不同抽象層級套用。本書提供的尺度是作者的工作經驗,僅供參考。

1–10 的尺度範例#

Integration Strength#

  • 1 = Contract coupling
  • 3 = Model coupling
  • 8 = Functional coupling
  • 9 = Symmetric functional coupling
  • 10 = Intrusive coupling

Distance#

  • 1 = 同物件不同方法
  • 2 = 同 namespace/package 不同物件
  • 3–7 = 不同 namespace/package
  • 8 = 不同 library
  • 9 = 分散式系統中不同服務
  • 10 = 不同廠商實作的不同系統

Volatility#

  • 1 = 不再演進的 legacy
  • 3 = supporting 或 generic 子領域
  • 10 = core 子領域,或被 core 帶出的 inferred volatility

公式#

MODULARITY = |STRENGTH - DISTANCE| + 1
BALANCE    = max(MODULARITY, (10 - VOLATILITY + 1))
           = max(|STRENGTH - DISTANCE|, 10 - VOLATILITY) + 1

實例#

Example 1:ML 服務讀 Operational DB#

WolfDesk 的 Distribution 模組透過 ML 模型分案,模型部署在第三方雲端服務上,且直接吃 Support Cases Management 的 operational DB:

  • Strength:模型直接複製 → Model coupling = 3
  • Distance:跨公司系統 → 10
  • Volatility:上游是 core 子領域 → 10
BALANCE = max(|3 - 10|, 10 - 10) + 1 = 8

若改用 integration contract,分數會跳到 10:

BALANCE = max(|1 - 10|, 10 - 10) + 1 = 10

Example 2:同 module 內的 Aggregate#

SupportCaseMessage 在同一 namespace,必須同 transaction 提交(DDD 中屬於同一 aggregate):

  • Strength:functional coupling = 8
  • Distance:同 namespace = 2
  • Volatility:core 子領域 = 10
BALANCE = max(|8 - 2|, 10 - 10) + 1 = 7

Example 3:跨服務重複的業務規則#

WolfDesk 把功能拆成微服務後,「能否升級案件」的業務規則同時實作在 Support Cases Management 與 Distribution 兩個服務中:

  • Strength:symmetric functional coupling = 9
  • Distance:跨服務 = 9
  • Volatility:core 子領域 = 10
BALANCE = max(|9 - 9|, 10 - 10) + 1 = 1

最低分 1 直接揭示問題:把「易變、業務關鍵」的功能複製到「低生命週期耦合」的服務,是設計災難。

Example 4:與 Legacy 系統的「不漂亮」整合#

新微服務直接讀 legacy 系統的 DB / message bus 等私有元件:

  • Strength:intrusive = 10
  • Distance:同公司不同系統 = 9
  • Volatility:legacy 不再演進 = 1
BALANCE = max(|10 - 9|, 10 - 1) + 1 = 10

雖然 strength + distance 完全失衡,但極低的易變性把整體拉回最佳分。這正是「balanced coupling」想表達的:單看 strength 不足以判斷設計品質

關於數字尺度的提醒#

作者選的範圍適用於他的場景。對你而言,最大距離可能不是「跨廠商」,而是「分散式服務」甚至「monolith 中不同模組」。

重點不是死記範圍,而是理解三個維度如何彼此補償:

BALANCE = MODULARITY OR NOT VOLATILITY
        = (STRENGTH XOR DISTANCE) OR NOT VOLATILITY

重點整理#

評估設計時可以問三組問題:

  • 整合穩定嗎?(強度 ↔ 易變性)
  • 變更成本高嗎?(易變性 ↔ 距離)
  • 走向模組化還是複雜化?(強度 ↔ 距離)

三題答完,BALANCE 公式自然浮現。

下一章將討論時間維度的進階議題——Rebalancing Coupling:當系統環境改變時,如何辨識並重新調整耦合力道。