複雜性由兩個原因造成:依賴(dependencies)與模糊(obscurity)。本節在高層次探討這兩個因素,後續章節會把它們連結到具體的設計決策。
依賴(Dependencies)#
本書定義:當一段程式碼無法獨立被理解或修改、必須同時考慮或修改其他程式碼時,就存在依賴。
常見例子
- 網站背景色:所有頁面共用同一個背景,改一頁就得改所有頁
- 網路協定(network protocol):發送端與接收端各自實作,但兩端必須遵循同一份協定,改一端往往得改另一端
- 方法簽章(signature):方法的實作與所有呼叫端之間存在依賴;新加參數時,所有呼叫處都得跟著改
依賴無法完全消除#
- 依賴是軟體的根本構成,事實上我們會刻意引入依賴——每寫一個新類別,就在它的 API 周圍建立了依賴
- 設計目標不是消滅依賴,而是:
- 減少依賴數量
- 讓剩下的依賴盡可能簡單且明顯
依賴形式的優劣#
回到網站背景色例子:
- 舊版:所有頁面互相依賴,且依賴不明顯且難以管理
- 新版:依賴轉移到
bannerBg變數的 API,新依賴明顯且可管理- 開發者搜尋變數名就能找到所有使用點
- 編譯器會幫忙:變數重新命名後,舊呼叫處會出現編譯錯誤
模糊(Obscurity)#
模糊指的是「重要資訊不顯而易見」。
範例
- 變數命名太籠統,看不出意涵(例如只叫
time) - 文件沒寫變數的單位,只能掃整份程式碼推敲
- 新增一個錯誤狀態時,還必須在訊息表中加入對應字串——但這個依賴對閱讀狀態宣告的人並不顯而易見
- 同一個變數名用在兩種不同用途,呼叫端難以判斷哪一個
**不一致(inconsistency)**是模糊的主要來源之一。
模糊也是設計問題#
- 文件不足會造成模糊,第 13 章會專門討論文件問題
- 但根本上,乾淨且顯而易見的設計需要的文件比較少
- 需要大量文件才能解釋的設計,本身就是紅旗(red flag)
兩個成因如何引發三個徵兆#
| 成因 | 引發的徵兆 |
|---|---|
| 依賴 | 變更放大、高認知負擔 |
| 模糊 | 未知的未知、認知負擔 |
只要找到能同時降低依賴與模糊的設計手法,就能降低軟體的複雜性。