遺留碼與改動兩難 (Legacy Code & the Change Dilemma)

★★★★★Draft

FromWELC

📚 From the Books

遺留碼與改動兩難 (Legacy Code & the Change Dilemma)Legacy Code

Feathers 給遺留碼一個刺耳但實用的定義:沒有測試的程式碼,就是遺留碼。不管它多新、多漂亮,只要你不能改一行就馬上知道有沒有壞,你就是在「編輯並祈禱」。這一頁講的是這個兩難的形狀——為什麼保留既有行為這麼難,以及為什麼「不敢改」本身會把系統推向更壞的地方。

🧠 Why It's a Problem

遺留碼的痛不在於「舊」,而在於改它的時候沒有回饋。Feathers 把所有變更歸成四個理由,但真正決定難度的不是理由,而是它動到了哪個維度:

四種變更裡,唯一橫跨全部的挑戰是同一件事——保留既有行為。使用者信任的是行為;你加一個他們喜歡的行為叫功能,你動壞一個他們依賴的行為就叫 bug。而幾乎沒有一次改動能保證「只加不動」:即使只是介面多一顆按鈕,渲染都會有微妙差異。

IMPORTANT

從技術角度看,重要的區分不是「功能 vs. bug」,而是 新增行為 vs. 改變既有行為。前者相對安全,後者是所有風險的來源——而你通常沒辦法完全避開後者。

⚖️ 兩種工作方式:編輯並祈禱 vs. 覆蓋並修改

面對一次改動,你其實在兩種姿態裡選一個:

Edit and Pray — 編輯並祈禱(多數團隊的預設)
1. 小心翼翼研究要改的地方
2. 動手改
3. 把相關路徑點一遍、跑一跑
4. 覺得「應該沒問題」→ 送出

問題:步驟 3 的「跑一跑」是靠人肉、靠運氣。你祈禱自己想到了所有會被波及的地方。改動越大、系統越糾纏,這個祈禱越不可靠——而你完全不知道自己漏了什麼。

Cover and Modify — 覆蓋並修改(有網子的改法)
1. 先用測試「蓋住」要改的區域(安全網)
2. 在網子保護下動手改
3. 測試立刻告訴你有沒有踩到既有行為
4. 綠燈 → 送出;紅燈 → 你當場就知道踩到哪

差別不在「更勤勞」,而在回饋的來源:不是你的信心,是測試的差異。這就是為什麼 Feathers 說——沒測試的碼是遺留碼,因為它只能用祈禱的方式改。

WARNING

投入更多人力審查不能替代測試覆蓋。再多雙眼睛盯著 diff,也回答不了「我有沒有弄壞別的東西」——只有能重跑的測試回饋能。

🔁 恐懼迴圈:不敢改如何讓系統更爛

大多數團隊用「最小化改動、沒壞別修」來管理風險。這個保守策略看似安全,其實在複利式地累積代價:

TIP

「Pay now or pay later」——寫測試現在要花時間,但不寫的利息會隨每次改動累積。而且變更會聚集:今天這塊碼你改到了,很快會再改到。先在這塊鋪網,幾乎總是划算。

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading