模組五|重構期的品質與節奏(Day 22–26)
我在整理開發紀錄的時候,看到一段讓我心裡一沉的曲線。
其中一個新專案,開發量連續四個月掉到近乎停擺,最低的那個月,只剩高峰期的 3%。
我的第一反應是:這個專案被放掉了。
然後我把四個 repo(新舊各兩套)的曲線並排放在一起,發現我完全看錯了。
以下是連續八個月的開發量,換算成相對指數(各專案以自己在這段期間的高峰為 100):
| 觀察期第 N 個月 | 新專案 A |
|---|---|
| 1 | 29 |
| 2 | 69 |
| 3 | 19 |
| 4 | 3 |
| 5 | 9 |
| 6 | 5 |
| 7 | 92 |
| 8 | 100 |
第 3 到第 6 個月,掉到個位數。
如果你只看這一條,結論很明顯:這個專案停了四個月,然後不知為何又活過來。
而「停了四個月」在重構這件事上,通常代表一件事:有人把資源抽走了,而這個專案可能永遠回不來。
然後我把同一段期間的另外三個 repo 也拉出來:

四條線疊在一起才看得出那個「安靜的四個月」不是意外,它在四個專案上都出現過,只是時間點不同。單看一條線你會以為是團隊懈怠;四條並排之後,形狀本身就是解釋。
| 第 N 個月 | 舊系統 A | 舊系統 B | 新專案 A | 新專案 B |
|---|---|---|---|---|
| 1 | 5 | 29 | 29 | 53 |
| 2 | 33 | 59 | 69 | 100 |
| 3 | 12 | 100 | 19 | 61 |
| 4 | 0 | 61 | 3 | 83 |
| 5 | 2 | 54 | 9 | 20 |
| 6 | 23 | 34 | 5 | 25 |
| 7 | 100 | 38 | 92 | 48 |
| 8 | 96 | 70 | 100 | 60 |
看第 3 到第 6 個月那四行。
新專案 A 掉到個位數的同時:
也就是說:團隊沒有停工。那四個月,主力在別的地方。

拼起來的故事是這樣的:
新專案 A 是第一個被重構的系統。它在更早之前就打出了第一個正式版本(Day 5 講過,第四個月就有了)。
所以在這段觀察期,它已經進入上線後的驗收期。
證據在改動的內容裡:那四個月的改動,幾乎全部是「修復 + 驗收單號」的形狀:沒有新功能、沒有重構,都是使用者回報的問題。
而團隊的主力,早就轉場到新專案 B 去了(Day 5 講過那個接力:第一個專案收斂的那個月,正好是第二個起步的月份)。
所以「停滯」是我用錯的詞。
正確的說法是:那個專案進入了它該有的狀態。

一個專案的開發量下降,有兩種完全相反的可能:
| 現象 | 可能是 | 怎麼分辨 |
|---|---|---|
| 開發量掉到谷底 | 它做完了 | 改動類型幾乎全是修復;其他專案有在動 |
| 開發量掉到谷底 | 它被放掉了 | 沒有任何改動;團隊也沒有轉去別的地方 |
分辨的關鍵不在那條曲線本身,在「同時間別的地方發生了什麼」。
這就是為什麼看單一 repo 會誤判:你缺的不是資料,是對照組。
而我覺得這件事可以推得更遠一點:
重構的成功指標,不是 commit 一直很多,是它能不能安靜下來。
一個永遠很忙的專案,通常代表它永遠有沒做完的部分。
第 7、8 個月,新專案 A 從 5 跳回 92、100。
如果按前面的邏輯,「它做完了」那為什麼又忙起來?
答案在同一張表:同一時間,舊系統 A 也從 2 跳到 100。
兩邊同時衝刺。 而這正是 Day 13 講過的那件事:切換前的最後功能對齊。
那段時間在做的是:把所有「新系統有、舊系統沒有」和「兩邊行為不一致」的地方一次補平,好讓最後一批使用者可以切換過去。
所以第二波的性質是下線前的收尾,而不是重構重新啟動。
而在那之後,舊系統就掉到斷崖,然後歸零。
把整段拼起來,一個大型重構的節奏長這樣:
衝刺 → 首版 → 收斂 → 驗收期(看起來像停滯)
→ 下線前的最後對齊(兩邊同時衝)→ 舊系統歸零 → 維護
我覺得最反直覺的是第四段。因為那一段在數字上長得跟「失敗」一模一樣,但它其實是整個過程裡最健康的一段:
系統上線了、在被使用、問題在收斂、而團隊的注意力已經去做下一件事。
這就是重構該有的樣子。
這裡值得停一下,把 Day 5 的伏筆收回來。
Day 5 講過我們沒有選擇 Big Bang Rewrite,而是按業務域一塊一塊搬,讓計畫「隨時可以停」。
現在把那四個月放回去看:
如果當初是大爆炸式重寫,那四個月會發生什麼?
答案是:專案會死。
因為 Big Bang Rewrite 在完成之前,手上永遠是「一個做到一半、不能上線的東西」。當團隊主力被調去做別的事、而這個專案連續四個月只有零星改動:
沒有人會相信它還會完成。 而一旦停下來,重啟的成本會高到讓「乾脆不要做了」變成理性的選擇。
而我們的情況是:那個專案在停下來之前已經上線了。所以那四個月不是風險,是成果在被使用。
一個可以隨時停下來的計畫,才有資格經歷低潮。
如果 commit 數量會誤導,那該看什麼?
我的答案在 Day 13 講過,這裡再確認一次:
看「舊系統還差什麼才能關掉」。
這個指標的好處是它不會被假象欺騙:
而且它天然地把「共存期的成本」算進去了:那段最貴、也最容易被忽略的日子(Day 13)。
一、這個判斷需要多個 repo 的資料。 如果你的重構只有一個專案、沒有對照組,那條曲線的低谷就真的很難解讀。你只能靠記憶,而記憶不可靠(我自己就記錯過那四個月的原因)。
二、「安靜是好事」這句話很容易被濫用。 一個真的被放掉的專案,也很安靜。差別在於「有沒有人在用它」,而那個數字不在 git 裡。所以這個判準不能單獨使用。
三、對外溝通仍然困難。 你很難跟主管解釋「這四個月開發量很低是好事」。比較有效的講法是換一個指標:不要報「這個月做了幾件事」,報「舊系統還剩幾個模組沒切換」。後者在那四個月裡是有進展的(使用者在陸續切換),而前者看起來像停擺。
模組五到這裡結束。這五天講的與其說是「怎麼寫程式」,更像是重構這件事在時間軸上長什麼樣:為什麼一直在修 bug、最好的改動是刪掉一萬行、有些醜東西不能改、以及看起來停滯的那四個月。
明天開始模組六,最後四天。Day 27 講一個問題:人會離職、記憶會消失,怎麼讓「為什麼這樣做」留下來?