屏蔽例外(exception masking):在系統的低層偵測並處理例外,讓上層完全不需要意識到該情況。
這在分散式系統特別常見。
範例 1:TCP 屏蔽封包遺失#
- 封包可能因錯誤、壅塞而遺失
- TCP 內部重送遺失的封包
- 所有資料最終都會到達;客戶端完全不知道有封包丟過
範例 2:NFS 屏蔽伺服器當機(具爭議)#
NFS(網路檔案系統)的策略:
- 伺服器當機或無回應 → 客戶端重試請求直到成功
- 客戶端的低階檔案系統碼不向上層回報任何例外
- 應用程式所做的檔案操作會hang 直到完成
- hang 太久時,客戶端會在 console 印
NFS server xyzzy not responding still trying
許多使用者抱怨應用 hang 住,建議 NFS 改成拋例外。但作者認為回報例外會讓事情更糟。
為什麼屏蔽更好#
- 應用程式失去檔案存取權後,本來就做不了什麼有用的事
- 應用各自重試 → 還是 hang,且邏輯散落各處(編譯器不該管這個!)
- 應用各自中止並回報 → 呼叫端多半也不知道怎麼辦,連鎖中止 → 整個工作環境崩潰
- 伺服器恢復後還得重啟所有應用
最好的方案:
- NFS 屏蔽錯誤、讓應用 hang
- 應用不需任何處理伺服器問題的程式碼
- 伺服器回來後 無縫繼續
- 使用者真的等不下去 → 自己手動中止應用
屏蔽 = 把複雜性下拉#
屏蔽例外不適用於所有情境,但適用時威力強大。
- 介面變窄(少幾個例外要使用者認識)
- 功能加深(屏蔽邏輯本身是新功能)
- 結果:類別變更深
屏蔽例外是「把複雜性往下拉」原則的範例。