複雜性由兩個原因造成:依賴(dependencies)模糊(obscurity)。本節在高層次探討這兩個因素,後續章節會把它們連結到具體的設計決策。

依賴(Dependencies)#

本書定義:當一段程式碼無法獨立被理解或修改、必須同時考慮或修改其他程式碼時,就存在依賴。

常見例子

  • 網站背景色:所有頁面共用同一個背景,改一頁就得改所有頁
  • 網路協定(network protocol):發送端與接收端各自實作,但兩端必須遵循同一份協定,改一端往往得改另一端
  • 方法簽章(signature):方法的實作與所有呼叫端之間存在依賴;新加參數時,所有呼叫處都得跟著改

依賴無法完全消除#

  • 依賴是軟體的根本構成,事實上我們會刻意引入依賴——每寫一個新類別,就在它的 API 周圍建立了依賴
  • 設計目標不是消滅依賴,而是:
    • 減少依賴數量
    • 讓剩下的依賴盡可能簡單且明顯

依賴形式的優劣#

回到網站背景色例子:

  • 舊版:所有頁面互相依賴,且依賴不明顯且難以管理
  • 新版:依賴轉移到 bannerBg 變數的 API,新依賴明顯且可管理
    • 開發者搜尋變數名就能找到所有使用點
    • 編譯器會幫忙:變數重新命名後,舊呼叫處會出現編譯錯誤

模糊(Obscurity)#

模糊指的是「重要資訊不顯而易見」。

範例

  • 變數命名太籠統,看不出意涵(例如只叫 time
  • 文件沒寫變數的單位,只能掃整份程式碼推敲
  • 新增一個錯誤狀態時,還必須在訊息表中加入對應字串——但這個依賴對閱讀狀態宣告的人並不顯而易見
  • 同一個變數名用在兩種不同用途,呼叫端難以判斷哪一個

**不一致(inconsistency)**是模糊的主要來源之一。

模糊也是設計問題#

  • 文件不足會造成模糊,第 13 章會專門討論文件問題
  • 但根本上,乾淨且顯而易見的設計需要的文件比較少
  • 需要大量文件才能解釋的設計,本身就是紅旗(red flag)

兩個成因如何引發三個徵兆#

成因引發的徵兆
依賴變更放大、高認知負擔
模糊未知的未知、認知負擔

只要找到能同時降低依賴與模糊的設計手法,就能降低軟體的複雜性。