複雜性常常源於複雜的條件邏輯。把條件的各個部分依「目的」命名成獨立函式,讓
if/else直接讀作意圖,而不是一串待解讀的判斷式。這其實是提取函式的一種,只因太有價值而單獨強調。
🧠 Why It's a Problem
一段又長又雜的條件式,會逼讀者停下來逐項推敲:這個 hour < 12 到底代表什麼情境?判斷式本身描述的是「怎麼判斷」,卻沒說出「在判斷什麼」。當條件與分支動作都攤成裸露的運算式時,意圖就埋在細節裡。
- 條件說不出意圖:
hour < 12、12 <= hour < 18這類判斷,讀者得自己翻譯成「早上」「下午」。 - 各部分都有目的:條件本身、成立時要做的事、不成立時要做的事,每一塊都值得用名字講清楚它的用途。
- 值得單獨命名的複雜片段:邏輯一旦複雜到需要停下來讀,就是把它封進一個名字的訊號。
TIP
分解條件式本質上就是提取函式,只是專門用在條件邏輯上。它之所以被單獨挑出來講,是因為為「條件的各部分」命名的回報特別高。
⚖️ Refactoring
機械步驟:① 對條件式套用提取函式,用「這在判斷什麼情境」來命名 → ② 對成立分支(then)的動作套用提取函式 → ③ 對不成立分支(else)的動作套用提取函式 → ④ 每一步後都測試。命名的準則永遠是「目的」而非「做法」。
前 — 判斷式裸露,意圖要自己翻譯
const hour = 20;
if (hour < 12) {
console.log("Good morning!");
} else if (hour < 18) {
console.log("Good afternoon!");
} else {
console.log("Good evening!");
}hour < 12、hour < 18 只說了怎麼比大小,沒說出「這是在區分早上、下午、晚上」。
後 — 每個條件都有名字
function isMorning(hour) {
return hour < 12;
}
function isAfternoon(hour) {
return 12 <= hour && hour < 18;
}
function isEvening(hour) {
return hour >= 18;
}
const hour = 20;
if (isMorning(hour)) {
console.log("Good morning!");
} else if (isAfternoon(hour)) {
console.log("Good afternoon!");
} else {
console.log("Good evening!");
}現在 if (isMorning(hour)) 直接讀作「如果是早上」——條件說出了它判斷的情境,而不是實作細節。
NOTE
分解條件式處理的是「把條件與分支各自命名」。若問題是巢狀太深、想用提早 return 把特例攤到最前面,那是另一個手法:以防衛敘句取代巢狀條件。
🔑 Takeaways
- 複雜性常來自複雜的條件邏輯;分解條件式就是替條件的各個部分依目的命名。
- 三個可下手的部分:條件本身、成立分支的動作、不成立分支的動作。
- 命名準則是「在判斷/做什麼」,不是「怎麼判斷/怎麼做」。
- 它是提取函式的一種特例,因回報高而被單獨強調。
- 巢狀條件的攤平是不同的問題,改用以防衛敘句取代巢狀條件。
No notes yet — jot your takeaways or Q&A here.