同一段邏輯以相同或幾乎相同的形式出現在多個地方。程式碼的可讀性始於命名與去重——重複讓你每次改邏輯都得同步好幾份拷貝,漏掉一份就是 bug。
🧠 Why It's a Problem
- 修改成本翻倍:改一處邏輯,就得記得把其他每一份拷貝也改到;只要遺漏一份,行為就不一致。
- 閱讀時得逐字比對:讀者得比對兩段是不是「真的一樣」,才敢判斷能不能一起維護。
- 掩蓋了共同意圖:這些重複片段其實是同一個概念,卻沒有一個名字把它們收攏起來。
- 本章把它歸在命名與基本邏輯這一組——程式碼的可讀性,始於命名與去重。
NOTE
最單純的形式,是同一個類別裡兩個方法出現相同的運算式。抽成一個函式、兩邊都改成呼叫,味道就消了。
⚖️ Refactoring
核心解法是 Extract Function:把重複的片段抽成一個具名函式,所有出現處都改成呼叫它。
前 — 折扣邏輯被複製了兩份
class Order {
priceForRegular(qty, unit) {
const base = qty * unit;
return base - Math.max(0, base - 100) * 0.05; // 折扣邏輯
}
priceForBulk(qty, unit) {
const base = qty * unit * 0.9;
return base - Math.max(0, base - 100) * 0.05; // 同一段折扣邏輯,又寫一次
}
}要改折扣規則(例如門檻從 100 改成 200),得記得兩處都改。
後 — 抽成一個具名函式,只有一份真相
class Order {
priceForRegular(qty, unit) {
return this.#applyDiscount(qty * unit);
}
priceForBulk(qty, unit) {
return this.#applyDiscount(qty * unit * 0.9);
}
#applyDiscount(base) {
return base - Math.max(0, base - 100) * 0.05;
}
}折扣規則現在只有一個家。改規則只動 #applyDiscount 一處,兩個呼叫端自動跟上。
🔑 Takeaways
- 重複的真正成本是**「同一件事得改很多遍」**,而遺漏其中一遍就製造出不一致。
- 標準解是 Extract Function:把重複片段抽成一個具名函式,各處改呼叫。
- 去重的同時也替那段邏輯取了名字,可讀性一併提升。
- 重複常和 長函式 相伴——長函式裡最容易藏著彼此雷同的片段。
No notes yet — jot your takeaways or Q&A here.