iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
ChatGPT & Codex

Codex 實戰 30 講:從個人開發到團隊導入系列 第 22 篇

Day 22. Codex 重構工作流:只消除當下理解障礙

  • 分享至 

  • xImage
  •  

用 Codex 協助重構

完成缺陷修正後,開發者常會看到周圍還有命名含糊、區塊過長或責任混在一起的程式。這些結構會增加閱讀時間,也讓下一次修改必須重新追查資料流向。

重構(Refactoring)可以整理內部結構,並維持外部可觀察行為。

Codex 能快速找出重複程式、長函式與可抽取區塊,也可能一次提出大量整理建議。

今天我們先把範圍收斂到已確認的理解障礙,只調整一個含意不清的名稱,並抽取一段責任明確的程式。其餘改善先記錄,不放進同一份差異。

重構要從具體的閱讀障礙開始

「幫我把這段程式整理得更好」缺少可判定的完成條件。

Codex 可以改名、拆檔、建立介面、加入設計模式,最後產生一份難以說明價值的大型差異。開發者需要指出哪一段理解成本正在阻礙目前工作。

例如 buildIssueReport() 同時準備標籤統計與議題排名,其中一個區域變數名為 result。閱讀者要走完整個迴圈,才知道它保存的是四種目標標籤的數量。

這裡有兩個可描述的障礙。變數名稱沒有表達資料用途,計數邏輯也埋在較長的報表流程中。

完成條件也要具體。result 改為 labelStats 後,名稱要能反映資料內容。計數區塊抽成 countTrackedLabels() 後,主函式要直接呈現「計算統計、建立排名、組合報表」的流程。

公開輸出、錯誤處理與排序結果都要保持一致。

外部行為先由現有測試固定

重構開始前,先執行與目標函式直接相關的測試,確認目前基準是綠燈。

前幾篇建立的案例已涵蓋大小寫、前後空白、重複標籤、零值、缺少 labels 與排名結果,這些都是本次需要保留的可觀察行為。

若測試目前失敗,先確認失敗是否和待重構程式有關。帶著紅燈開始整理,完成後很難判斷失敗來自既有問題或新差異。

若關鍵行為沒有測試保護,先停下來列出缺口,再由開發者決定補上特徵測試或縮小重構範圍。

測試通過後,也要保留實際命令、通過數量與工作目錄狀態。這份基準會用來比對重構後的結果。

輸出中若有已知警告,也要原樣記錄,避免完成後把警告消失誤認為重構成果,或漏看新出現的訊息。

先讓 Codex 畫出函式內的責任

修改前先要求 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() 的主要流程也能更快被讀懂。

最後由開發者判斷理解成本是否降低。測試證明已列出的案例維持,差異證明修改範圍符合計畫,人工閱讀則確認新名稱與函式邊界能協助下一次修改。

三項證據都具備後,這次重構便有足夠依據結束。

參考資料:


上一篇
Day 21. Codex 除錯工作流:從錯誤訊息到最小修正
下一篇
Day 23. Codex 程式碼審查:用 review 先標出可疑變更
系列文
Codex 實戰 30 講:從個人開發到團隊導入 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言