條件式通常出現在兩種情境:兩個分支都是正常行為,或一個分支正常、另一個是異常。在後者,用防衛敘句(提早
return)能顯出異常情況並非這個函式的邏輯核心。
🧠 Why It's a Problem
深巢狀的 if/else 逼讀者把每一層條件都記在腦裡,才走得到最裡面的核心邏輯。若某些分支其實只是「處理特例後就結束」,就沒必要讓它們把主線壓在最深處。
- 一正常、一異常:某個分支只是處理前置條件不成立的情況,處理完就該離場。
- 主線被埋太深:真正的核心邏輯縮在最內層,被層層條件包住。
- 想凸顯意圖:防衛敘句把「這些是特例、那個才是正事」的結構攤在最前面。
TIP
關鍵區分:兩分支都是正常行為時,保留 if/else 反而更誠實;只有在「這是異常、提早出場」時,才換成防衛敘句。
⚖️ Refactoring
機械步驟:① 挑出最外層、可作為防衛條件的分支 → ② 把它改寫成「條件成立就提早 return」 → ③ 測試 → ④ 對其餘的特例分支重複同樣動作 → ⑤ 拉平後,核心邏輯落在函式最後、不再縮排。
前 — 巢狀 if/else 把主線埋在底層
function calculatePay(employee) {
if (employee.isRetired) {
if (employee.age > 65) {
return 0;
} else {
return employee.pension;
}
} else {
if (employee.isOnLeave) {
return 0;
} else {
return employee.salary;
}
}
}要看懂「一般在職者領 salary」,得先穿過退休、年齡、請假三層判斷。
後 — 防衛敘句把特例提到前面
function calculatePay(employee) {
if (employee.isRetired) {
if (employee.age > 65) {
return 0;
}
return employee.pension;
}
if (employee.isOnLeave) {
return 0;
}
return employee.salary;
}每個特例判斷完就 return 離場,巢狀被拉平;return employee.salary 這條主線落在最後、一目了然。
NOTE
若條件分支不是「特例 vs. 主線」,而是「依型別選不同行為」,那該用的是 Replace Conditional with Polymorphism 而非防衛敘句。
🔑 Takeaways
- Guard Clauses 用提早 return 把異常/特例分支提到函式前面,讓核心邏輯浮出水面。
- 觸發訊號:一分支正常、另一分支是異常,且主線被巢狀埋得很深。
- 兩分支都正常時,保留 if/else 反而更清楚——別硬套。
- 依型別分岔的條件,改用 Replace Conditional with Polymorphism。
No notes yet — jot your takeaways or Q&A here.