模組三|遷移執行法與驗收(Day 12–16)
有一組數字我每次看都覺得很療癒:其中一套系統的統計模組,從 52 個頁面變成 24 個。
不是因為砍功能,是因為那 52 頁裡本來就有一半是重複的。
遷移最有價值的動作,是先決定哪些根本不用搬,不是把東西搬過去。
我們實際做的處置分三種,難度和爽度都不一樣。
其中一套系統有個內容管理模組,四個頁面。
我們搬完整個專案之後,它在新系統裡不存在,連目錄都沒有。
不是搬了之後刪掉,是從一開始就沒搬。因為盤查之後確認:沒有人在用。
四個頁面聽起來不多,但它的價值不只是省下搬的工。它省下的是往後每一次「這個模組要不要跟著改」的判斷成本。

這是最有感的一種。
舊系統有兩個統計模組:一個舊的、一個叫「新統計」的。它們同時存在、同時被使用,而且已經並存好幾年了。
規模是這樣:
| 頁面數 | 行數 | |
|---|---|---|
| 舊的統計模組 | 23 | 5,716 |
| 「新」統計模組 | 29 | 10,272 |
| 合計 | 52 | 15,988 |
而真正扎眼的是這個:兩邊有 8 個頁面檔名完全一樣,同樣的報表名稱,在兩個目錄下各有一份實作。
搬到新系統之後,只剩一個統計目錄、24 個頁面。
第三種比較低調但影響很大:趁搬的時候重新命名和分組。
舊系統的目錄名是六年前的用語,有些已經跟現在的業務對不上了。搬的時候我們順手把它們改成一致的命名慣例,並把一個混雜多種查詢的巨大目錄,拆成三個職責清楚的頁面。
其中一套系統的視圖目錄從 9 個變成 8 個。數字看起來只少一個,但裡面幾乎全部重新洗過牌。
這是我自己最好奇、也最該量的一個數字。
我把新舊兩邊的視圖目錄逐一對照,分成四類:
| 處置 | 說明 |
|---|---|
| 原樣搬遷 | 功能不變,只是換技術棧。佔大宗 |
| 重組或拆細 | 一個巨大目錄拆成數個職責清楚的頁面 |
| 合併 | 兩代並存的模組收成一個 |
| 不搬 | 整批淘汰 |
粗估下來,舊系統的功能大約有八成多被帶到新系統,其餘是刻意留下的。
這個比例我覺得是健康的。因為:
八成多這個數字的意思是:我們動了刀,但沒有偷渡產品決策。
這件事值得停下來想,因為它會再發生。
我的推測是:當年要改統計模組的時候,有人判斷「直接改風險太高」,於是開了一個新目錄重寫。
這個判斷本身沒有錯,甚至很專業。問題出在後面:
新的做完之後,舊的沒有被關掉。
可能是還有幾個報表沒搬完、可能是某些使用者習慣舊的、也可能只是沒有人負責喊停。於是兩套並存,一年、兩年、然後變成常態。
有沒有覺得很耳熟? 這正是 Day 13 講的共存期,只是那次我們有把它結束掉,而這次沒有。
所以我從這裡學到的是:「先做一個新的,舊的之後再說」是一個會產生長期成本的決定。 做這個決定的時候,一定要同時決定「舊的什麼時候關、誰負責關」。
否則你不是在重構,是在製造下一個要被重構的東西。

前面講整批淘汰講得很輕鬆,但實際上這是最難的一步——因為刪錯的代價很高,而「沒人用」很難證明。
我們用三個條件,三個都過才敢不搬:
條件一:前端沒有任何引用。
全專案搜這個模組的路由、API、元件。這是必要條件,但遠遠不夠,因為可能有人是直接打網址進去用的。
條件二:後端的 API 呼叫紀錄是空的。
這條最有力。看那幾支 API 在過去一段時間有沒有被呼叫過。這是唯一能反映「真實使用行為」的證據,前面那條只反映「程式碼裡有沒有寫」。
條件三:問業務。
聽起來很土,但不能跳過。因為有一種情況前兩條都抓不到:這個功能一年只用一次(年度結算、稽核報表)。你在三月盤查,它看起來完全沒被用過。
三條都過,才是「真的沒人用」。
而如果只有前兩條過、第三條沒問到人,我的建議是先不要刪,改成「保留但標記」,因為刪掉之後如果有人在年底來找你,你要重做的不只是那個功能,還有信任。
Day 8 提過舊系統的狀態管理裡有六個模組是空的:兩行程式碼、一個空物件、什麼都沒有,但全部被正式註冊了。
盤查的時候這種東西特別好認,而且它們幾乎都是可以直接不搬的。
一個東西「被建立、被註冊,但裡面沒有內容」,通常代表當初建立它的理由是結構對稱(別的模組都有,這個沒有很奇怪),不是實際需求。
這類東西不搬,零風險。
一、判斷「不用搬」比搬還花時間。 搬一個四頁的模組可能兩天;但要證明它可以不搬,可能要跑三種查證、等業務回覆一週。在時程壓力下,人會傾向直接搬——因為搬比較快、比較不用負責。 這是最需要抵抗的誘惑。
二、你會刪錯。 我們有幾個「確定沒人用」的東西,後來還是被問起。所以刪的時候要能還原,這也是為什麼分批、可回溯的刪除很重要(Day 28 會講我們後來怎麼把這件事工程化)。
三、重新命名會製造溝通成本。 你把某個模組改名了,但業務、客服、文件、教育訓練投影片裡還是舊名字。改名的技術成本是零,溝通成本不是。 這件事我們低估了。
明天 Day 15 講一件我很想做、但刻意忍住的事:改掉那些爛掉的 API 命名。我會講為什麼我們選擇先原樣搬過去、之後才統一改名,以及那份「舊名 → 新名」對照表真正的用途——它不是給人看的。