Claude Code 重構舊程式:先記錄行為,再細步搬動
先用特徵測試記錄目前行為,再逐步重構,核對回傳值、錯誤同副作用,避免順手改埋業務規則。
重構要保留嘅,未必只係回傳值
一個舊訂單模組可能有難明嘅分支,但背後係曾經修過嘅特殊情況。直接叫 Claude「寫得簡潔啲」,可能連呢啲行為一齊刪走。
先講清楚今次係改善結構,定係修改功能。純重構要保留外部可觀察行為,包括錯誤、順序、資料寫入同外部呼叫;發現可疑 bug 可以另外記錄,唔好偷偷修埋。
1. 讀公開介面同呼叫端
完整讀取 [模組]、直接呼叫端同相關測試,暫時唔改程式。 列出公開函數、輸入輸出、空值及錯誤行為、非同步次序,同外部副作用。將不尋常但可能有意保留嘅行為另列,附程式位置。 提出最小重構範圍,以及要先補嘅測試。未讀範圍明確寫出。
唔好只睇函數名。名稱亦可能出現喺設定、反射、序列化資料或者外部介面;改名未必係純本機文字替換。
2. 用特徵測試記錄現況
特徵測試(characterization test)係先描述現有程式實際做緊乜,唔係由理想設計推答案。佢唔代表現況全部正確,只係幫你分辨今次改動有冇改變行為。
沿用現有測試框架,為已盤點嘅可觀察行為加測試。今次只改測試,唔改正式程式。 涵蓋正常輸入、空值、可疑舊行為、錯誤同重要副作用。外部 IO 用受控替身或隔離整合環境,唔連正式服務。 喺重構前執行測試,核對通過原因。每項預期結果要由實際行為或已確認要求支持,唔好為咗綠燈一直調答案。
重要案例要人手睇 assertion 真係驗緊乜。必要時暫時引入一個明確錯誤,確認測試會失敗,再撤回該測試性改動。
3. 每次做一個細轉換
先揀資料依賴同副作用最清楚嗰段,唔一定係函數最尾。尾段可能正正係寫資料或者發通知,未必最容易抽離。
今次只做 [抽出指定 helper/局部重新命名]。 保留函數簽名、回傳值、預設值、條件判斷、錯誤同副作用次序。唔加新抽象、唔改依賴、唔順手修 bug。 改完跑相關特徵測試。失敗時先查原因,只撤回自己今次造成嘅改動,唔清空整個工作目錄。
抽函數、提早 return 同調換位置都未必天然等價。要留意閉包、this、短路求值、例外傳播、交易同非同步時序,唔好只因為差異看似機械式就免審。
4. 比較新舊結果
可以喺兩份隔離 checkout,用同一批受控輸入跑新舊版本。唔好喺有其他工作嘅目錄反覆 stash 同切版本,亦唔好用真實付款、通知或資料寫入做雙跑。
比較回傳、錯誤類型、必要記錄同外部請求內容。時間戳、隨機值等應先定可接受差異,唔係一律逐 byte 比較。抽樣相同只證明測過嘅輸入,唔代表已數學證明所有情況等價。
高風險邏輯可以增加性質測試或有隔離措施嘅影子驗證,但要確保唔會令副作用執行兩次。
公開介面改動要有遷移安排
如果由 getUser(id) 改成物件參數,就已經超出純內部搬動。可以先加相容入口、逐個遷移呼叫端,再確認外部使用者同舊版本都處理好,先移除舊入口。
唔好只因為 repo 入面搜尋唔到就刪:其他套件、腳本或者已發佈客戶端都可能仍然使用。每個中間版本是否可以運作,要實際驗證,唔係用咗「分階段」個名就自然成立。
交付要講清楚證據
將新增測試同結構改動分開呈現,方便審閱同選擇性復原;實際提交方式跟團隊規矩。留低測過嘅行為、未覆蓋範圍同發現但未處理嘅問題。
完成唔係「檔案由八百行變兩百行」,而係結構更容易理解,同時有足夠證據支持原有行為仍然保留。
文中工具 · 連結
- Claude Code CLI· 付費
開發者用 — terminal 入面同 Claude pair coding
睇完想同 Claude 一齊行一次?
撳一下,複製教學提示詞同全文到剪貼簿。 貼入 Claude.ai 或 Claude Desktop,再按文章逐步試做, 整理出適合你情況嘅草稿或清單;未確認嘅資料會留低畀你核對。