完成缺陷修正後,開發者常會看到周圍還有命名含糊、區塊過長或責任混在一起的程式。這些結構會增加閱讀時間,也讓下一次修改必須重新追查資料流向。
重構(Refactoring)可以整理內部結構,並維持外部可觀察行為。
Codex 能快速找出重複程式、長函式與可抽取區塊,也可能一次提出大量整理建議。
今天我們先把範圍收斂到已確認的理解障礙,只調整一個含意不清的名稱,並抽取一段責任明確的程式。其餘改善先記錄,不放進同一份差異。
「幫我把這段程式整理得更好」缺少可判定的完成條件。
Codex 可以改名、拆檔、建立介面、加入設計模式,最後產生一份難以說明價值的大型差異。開發者需要指出哪一段理解成本正在阻礙目前工作。
例如 buildIssueReport() 同時準備標籤統計與議題排名,其中一個區域變數名為 result。閱讀者要走完整個迴圈,才知道它保存的是四種目標標籤的數量。
這裡有兩個可描述的障礙。變數名稱沒有表達資料用途,計數邏輯也埋在較長的報表流程中。
完成條件也要具體。result 改為 labelStats 後,名稱要能反映資料內容。計數區塊抽成 countTrackedLabels() 後,主函式要直接呈現「計算統計、建立排名、組合報表」的流程。
公開輸出、錯誤處理與排序結果都要保持一致。
重構開始前,先執行與目標函式直接相關的測試,確認目前基準是綠燈。
前幾篇建立的案例已涵蓋大小寫、前後空白、重複標籤、零值、缺少 labels 與排名結果,這些都是本次需要保留的可觀察行為。
若測試目前失敗,先確認失敗是否和待重構程式有關。帶著紅燈開始整理,完成後很難判斷失敗來自既有問題或新差異。
若關鍵行為沒有測試保護,先停下來列出缺口,再由開發者決定補上特徵測試或縮小重構範圍。
測試通過後,也要保留實際命令、通過數量與工作目錄狀態。這份基準會用來比對重構後的結果。
輸出中若有已知警告,也要原樣記錄,避免完成後把警告消失誤認為重構成果,或漏看新出現的訊息。
修改前先要求 Codex 唯讀分析 buildIssueReport()。它需要說明輸入與輸出、區域變數用途、標籤統計區塊、排名區塊,以及函式依賴的外部工具。
每項結論都要附上程式位置,讓開發者核對分析是否符合真正的執行路徑。
接著讓 Codex 提出單一重構計畫。計畫只包含 result 改名與抽取 countTrackedLabels(),並說明函式參數、回傳值和放置位置。
若抽取後需要改變公開型別、移動跨模組責任或新增相依套件,代表原計畫已經超出本次範圍。
應先向 Codex 描繪目標區域,再用小批次處理單一整理主題。每一批都要說明目前行為、結構改善與維持行為的驗證方式。
今天先把這個做法縮到一個函式,讓每一行差異都能對應到已確認的閱讀障礙。
第一輪可以使用以下提示詞(Prompt):
請先讀取 AGENTS.md、src/report/build-issue-report.ts,以及直接驗證 buildIssueReport() 的測試。
本次只分析以下理解障礙:
1. buildIssueReport() 內的 result 無法直接看出保存的是標籤統計。
2. 四種目標標籤的計數區塊混在報表組合流程中。
這一輪保持唯讀。請完成以下工作:
1. 說明函式的輸入、輸出與現有責任,附上程式位置。
2. 找出 result 的所有讀寫位置與實際資料形狀。
3. 說明計數區塊依賴哪些輸入,是否有副作用。
4. 確認哪些現有測試保護大小寫、空白、去重、零值、缺少 labels 與排名。
5. 提出只包含改名與抽取方法的計畫,以及重構前後的驗證命令。
不要修改檔案,不要提出拆檔、設計模式、套件更新或其他清理。
若現有測試不足以保護外部行為,請停止並列出缺口。
變數改名看似簡單,仍需要確認它在每個分支中的用途。
result 若從初始化、累加到回傳都代表標籤統計,改成 labelStats 能降低閱讀成本。若其中一個分支把它暫時當成其他資料使用,應先釐清責任,不能只做全檔字串取代。
Codex 改名時應使用語言工具或精確的程式範圍,避免改到無關的測試文字、文件範例或另一個同名變數。
這次名稱是函式內部細節,公開 JSON 欄位 labelStats 已經存在時也不需要跟著改變。內部識別字與外部契約要分開確認。
改名完成後,先檢查差異中是否只有同一個符號的宣告與引用。Type Check 可以找出遺漏引用,相關測試則確認執行結果。
若 Codex 順手調整周圍名稱,應要求它還原未經確認的部分。
抽取方法(Extract Method)會把一段已有清楚責任的程式移到具名函式。
這次將四種標籤計數抽成 countTrackedLabels(issues),回傳原有的統計物件。buildIssueReport() 仍負責組合統計與排名結果,公開函式簽章保持原狀。
抽取時要檢查輸入是否足夠,並保留正規化、去重與累加順序。
若原計數區塊直接改寫傳入的 issue,抽取後就需要把副作用說清楚。若它只讀取資料並建立新物件,參數與回傳值會比較清楚。
Codex 不能為了讓函式看起來通用,加入目前沒有使用情境的選項或泛型。
新函式的位置應遵循專案慣例。它可以留在同一檔案作為私有輔助函式,避免為一個局部整理新增模組與公開匯出。
函式名稱、輸入與輸出已足以說明責任時,不需要加入重述程式的註解。
開發者確認唯讀分析、測試基準與計畫後,再讓 Codex 進入修改階段。
本次允許的產品差異只有兩項:將 result 改名為 labelStats,以及把既有計數區塊抽成 countTrackedLabels()。若實際程式與分析不一致,代理人要停下回報。
我已確認分析結果與測試基準。請依照計畫重構 buildIssueReport():
1. 將函式內代表四種標籤統計的 result 改名為 labelStats。
2. 將現有標籤計數區塊抽成同檔案內的私有函式 countTrackedLabels(issues)。
3. 保留原有正規化、去重、零值、缺少 labels 與累加順序。
4. 保留 buildIssueReport() 的公開簽章、回傳形狀、排名規則與錯誤處理。
不得修改測試期待值、輸出欄位、其他模組、套件、設定與 README。
不得加入新的抽象層、選項、泛型或順手清理。
修改後先執行直接相關測試,再依 AGENTS.md 執行完整 Test、Lint、Type Check、Build 與 Formatter 檢查。
最後顯示 git status、git diff、實際命令與結果,不要建立 commit。
重構後先閱讀差異,不急著用測試綠燈結束任務。這份差異(Diff)應清楚呈現同一個變數的改名,以及原計數程式移入具名函式。
若出現條件式改寫、預設值變動、陣列排序調整或輸出物件重排,都需要 Codex 解釋其必要性,無法對應本次目標的差異應還原。
接著比較重構前後的測試結果。直接相關測試驗證標籤統計與排名行為,完整測試檢查其他呼叫端,Type Check、Lint、Build 與 Formatter 則提供不同面向的結構證據。
任何未執行項目都要記錄原因,不能用代理人的文字推論代替命令結果。
還要重新閱讀 buildIssueReport()。主函式若能直接看出統計與排名如何組合,而且進入 countTrackedLabels() 後能理解四種標籤如何計算,這次重構已處理原先障礙。
若需要在兩個函式間反覆跳轉才能理解簡單流程,抽取位置或函式邊界就需要重新評估。
Codex 在分析時可能還會找到重複常數、相似迴圈、較長參數列或可拆分檔案。
這些發現可以放進「延後項目」,附上位置與影響,不在本次繼續修改。重構範圍有清楚終點,差異才容易由另一位開發者審查。
本篇的練習完成時,應保留重構前的綠燈基準、唯讀分析、兩項結構差異、重構後的驗證結果與延後項目。外部行為維持原狀,buildIssueReport() 的主要流程也能更快被讀懂。
最後由開發者判斷理解成本是否降低。測試證明已列出的案例維持,差異證明修改範圍符合計畫,人工閱讀則確認新名稱與函式邊界能協助下一次修改。
三項證據都具備後,這次重構便有足夠依據結束。