我至今仍清楚記得新公司第一天上班時,拿到儲存庫並首次開啟程式碼的那一刻。
一個 3,000 行的檔案裡,各種邏輯糾結在一起。我不禁嘆了口氣。
「到底是誰寫成這樣的……」
但幾個月後,新人看著我寫的程式碼,也露出了完全相同的表情。那時我才明白,舊程式碼不是某一個人的錯。
先說結論。
舊程式碼之所以挨罵,不是因為程式碼很差,而是因為撰寫當時的脈絡已經消失了。
今天想分享我的經驗:為什麼舊程式碼總會成為責怪的對象,以及面對它時如何少受點傷。
什麼是舊程式碼?和老舊的程式碼不同嗎
先釐清一點:舊程式碼不只是「老舊的程式碼」。
依我的經驗,標準只有一個:因為沒有測試而不敢修改的程式碼。
Michael Feathers 在《修改舊程式碼的藝術》中將舊程式碼定義為「沒有測試的程式碼」。即使只寫好一週,只要因為沒有測試、每次修改都讓人提心吊膽,那就是舊程式碼。
反過來說,就算是 10 年前的程式碼,只要測試完整,也能放心修改。
所以問題不在年齡,而在於你是否確信「改這裡不會讓其他地方爆掉」。
為什麼舊程式碼總是被嫌棄
整理原因後,大致有三個。
1. 撰寫程式碼的人已不在公司
沒有人可以詢問當初為什麼要這樣寫。沒有註解或文件時,剩下的只有程式碼和我的想像力。
2. 脈絡消失了
糾結得不合常理的程式碼,通常都有它的故事:緊迫的期限、奇怪的需求,或是為了避開特定 OS 版本的錯誤。
當時可能是最佳解,但那些背景不會留在程式碼裡。留下的只有結果,所以現在看來便難以理解。
3. 別人的程式碼本來就看起來很奇怪
老實說,這是最主要的原因。自己的程式碼,流程都在腦中;別人的程式碼,卻得從頭追流程。
那份煩躁最後就會變成「為什麼要這樣寫」。
來看看下面的程式碼。乍看之下,不知道為什麼有這個條件,是很典型的舊程式碼痕跡。
// 沒有人知道為什麼要扣除 30
if user.type == "B" && amount > 0 {
finalPrice = amount - 30 // 2019年促銷活動的殘留?
}
無從得知這個- 30現在是否仍有必要,或只是舊活動留下的痕跡。這樣的一行行程式碼累積起來,就成了舊程式碼。
那麼,該如何面對舊程式碼
面對陌生的舊程式碼,很容易想著「全部重寫吧」,但其實有更好的方法。
我現在遵守三個原則。
- 不要隨便重寫 — 能運作的程式碼裡,融入了多年累積的各種錯誤處理。重新撰寫,就得從頭再踩一次。
- 修改前先補測試 — 用測試固定目前的行為,修改後哪裡壞掉就能立即看見。
- 留下修改原因的痕跡 — 把理由寫在提交訊息或註解裡,至少能讓下一個人少一點怨念。
尤其第三點很重要。這是唯一能避免把我現在的煩躁傳給未來某個人的方法。
說到底,今天的新程式碼也是明天的舊程式碼
我花了 6 個月才明白一件有點空虛的事:現在用心寫的程式碼,幾年後也會成為被某人嫌棄的舊程式碼。
接受這點後,我反而放鬆了。不再執著於完美,而是轉向替下一個人少留一點麻煩。
如果你現在正對著陌生的舊程式碼嘆氣,請偶爾想起,寫下它的人當天也已經盡了最大的努力。然後安靜地先補上測試吧。這似乎是彼此都少受傷的方式。

