本節對應原書第 8 章前兩節,談償還技術債的工具流程

工具篇#

Figure 8.1: 償還技術債的關鍵面向

償還技術債的工具大致分為四類。

理解類工具(Comprehension Tools)#

大型系統(百萬行級)難以一眼掌握。理解類工具透過視覺化幫助讀懂結構:

  • 控制流視覺化
  • 資料流分析
  • 呼叫序列分析
  • 繼承圖

評論工具、複製偵測、度量工具#

  • 架構評論工具(architectural critique tools):偵測架構級違規。
  • 設計評論工具(design critique tools):偵測設計壞味道。
  • 程式碼分析工具(code analysis tools):偵測 source code 層級的潛在 bug pattern。
  • 程式碼複製偵測(code clone detectors):複製常常是 Duplicate Abstraction、Unfactored Hierarchy 的訊號。
  • 度量工具(metric tools):以數值表達設計品質。例如 WMC(Weighted Methods per Class) 可作為偵測 Insufficient Modularization 的依據。

技術債量化與視覺化工具#

量化技術債仍是難題:

  • 沒有公認的構成因子
  • 沒有標準衡量方式

現有工具仍受限於只考慮少數因子。

重構工具#

  • 辨識重構候選:分析程式碼,提示哪裡需要重構與適用的重構步驟(仍處於早期階段)。
  • 執行重構:IDE(如 IntelliJ、Eclipse)內建有限的自動重構功能(如 extract methodrename)。

實務考量#

工具是指示,不是判決。

  • 評論工具的違規清單必須人工依脈絡複查,避免假陽性。
  • 重構工具仍不成熟——例如 extract class 經常產生無法編譯的中間狀態;複雜壞味道(如 Hub-like Modularization)尚無自動支援。
  • 採購商業工具前先做相容性試用(書中提到一個案例:UML 分析工具因 XMI 不相容而完全無法使用)。

流程篇#

重構的常見阻礙#

  • 缺乏基礎設施與工具:沒有單元測試、沒有靜態分析——典型雞生蛋蛋生雞問題。
  • 害怕弄壞既有程式碼:「If it ain’t broke, don’t fix it」是阻力最強的口號。
  • 聚焦功能完成:管理層視重構為「不必要的返工」。
  • 心理障礙:對「房間裡的大象」視而不見、「先做完再說」的文化。

取得 buy-in#

「technical debt」這個詞由 Ward Cunningham 提出,正是為了讓非技術背景的管理者也能感同身受

有效的策略:

  • 量化並視覺化技術債
    • 把技術債換算成金額(即使不精確也具震撼力)。
    • 顯示關鍵度量(如「複製比例 40%、超過組織標準 3% 十倍」)。
    • 把資料圖表化、呈現品質惡化趨勢(如 Cyclomatic complexity / LOC 隨版本攀升)。
  • 以小規模重構展示可行性
    • 一次只處理一個壞味道。
    • 重構前後量化品質、附比較圖。
    • 小成功累積信任,再爭取大規模授權。

IMPACT 重構流程模型#

在實務中,重構若沒有結構化流程就會變成混亂的修補。書中提出 IMPACT 模型:

Figure 8.2: IMPACT 重構流程模型

flowchart LR
    I[Identify / Mark<br/>辨識重構候選] --> P[Plan<br/>規劃重構活動]
    P --> A[ACt<br/>執行重構]
    A --> T[Test<br/>確保行為不變]
    T -.->|新候選| I
    T -.->|需求變動| P

各步驟要點:

  • Identify/Mark:手動審查 + 自動化工具,結合使用比單一手段更有效。
  • Plan:依 severity(單元 cycle vs. 多重 cycle)、scope(類別內 vs. 跨套件)、interdependence、可獲得收益、可用時間、是否有測試 等因素排序
  • ACt:執行計畫好的重構,可借助 IDE 提供的自動重構。
  • Test:每次重構後跑自動化迴歸測試

軼事:一個多執行緒應用 extract method 後所有測試通過、發布上線。幾個月後客戶回報崩潰——根因是重構誤改了執行緒終止邏輯,但因為多執行緒非確定性,測試沒抓到。 教訓:測試之外,還需人工 code review——尤其在關鍵與多執行緒模組。

償債最佳實踐#

在現實中(業務目標通常凌駕品質目標),以下實踐可幫助同時兼顧兩端:

  • 維護「TO-Refactor」清單,避免重構任務被遺忘。
  • 避免大爆炸式重構——一次只做一小部分;持續整合下,每次重構後都要跑自動化測試。
  • 缺單元測試 → 以「先寫測試 → 再重構」迭代打破雞生蛋問題。
  • 為重構任務(含更新設計文件)保留 buffer 時間
  • 重構配合 bug fix:「check-in code better than what you checked-out」。
  • 每次大版本發布後留時間還清最近累積的技術債,再進入下一輪開發。