🔧 重構

Refactoring — Martin Fowler 不改外部行為,只改內部結構

🎯 什麼情境該想到我

當你覺得某段程式碼「怪怪的、很髒」但講不出具體問題,或想判斷「該從哪裡開始重構」時。

⚙️ 怎麼用(把直覺變成可指認的清單)

常見壞味道 → 對應重構方向:

  • 重複程式碼 → 提煉並共用
  • 過長函式 / 過大類別 → 拆小(工具-提煉函式
  • 過長參數列 → 包成物件
  • 發散式變化(一個類別因多種原因而改)/ 散彈式修改(一個改動要動很多處)→ 重新歸位職責
  • 依戀情結(方法愛用別的類別資料)→ 搬移函式
  • 資料泥團 / 基本型別偏執 / 過度耦合的訊息鏈

🧪 我實際套用的紀錄

  • 2026-07-14:(待填)

⚠️ 注意

  • 聞到味道不代表一定要立刻改;權衡成本與風險,並確保有測試。

🔗 相關工具

  • 工具-小步重構 —— 聞到味道之後的行動節奏,一次改一小塊
  • 工具-提煉函式 —— 對付最常見那幾種味道(過長函式、重複程式碼)的主力手法

🎯 什麼情境該想到我

當你想改善程式結構、卻怕一改就壞掉時。

⚙️ 怎麼用

  1. 先確保有可靠測試(沒有就先補;見 工具-特徵測試)。
  2. 每次只做一個小改動(一個標準重構手法)。
  3. 每步都跑測試:綠燈才繼續,紅燈就退回上一步。
  4. 提交要頻繁:小步可回溯,出錯損失小。
  5. 重構與加功能分開做(別同時戴兩頂帽子)。

🧪 我實際套用的紀錄

  • 2026-07-14:(待填)

⚠️ 注意

  • 沒測試就大改=走鋼索。先建立安全網再動手。

🔗 相關工具

🎯 什麼情境該想到我

當你有一段程式碼「可以獨立命名、說明它在做什麼」,或想拆長函式、消重複時。最常用的重構手法。

⚙️ 怎麼用

  1. 找出一段內聚的程式碼(常是「這段在算 X」)。
  2. 抽成新函式,用意圖命名(名字說「做什麼」而非「怎麼做」)。
  3. 把用到的區域變數當參數傳入,回傳需要的結果。
  4. 原處改成呼叫新函式,跑測試確認行為不變。

好處:消除重複、讓函式各層抽象一致、用函式名取代解釋性註解。

🧪 我實際套用的紀錄

  • 2026-07-14:(待填)

⚠️ 注意

  • 若抽出後參數爆多,代表切點不對或該連資料一起搬(考慮搬移到別的類別)。

🔗 相關工具

🧰 即用工具

🦨 24 個壞味道 [[神秘命名]]・[[重複程式碼]]・[[過長函式]]・[[過長參數列]]・[[全域資料]]・[[可變資料]]・[[發散式變化]]・[[霰彈式修改]]・[[依戀情結]]・[[資料泥團]]・[[基本型別偏執]]・[[重複的 switch]]・[[迴圈]]・[[冗員元素]]・[[誇誇其談通用性]]・[[暫時欄位]]・[[訊息鏈]]・[[中間人]]・[[內幕交易]]・[[過大類別]]・[[異曲同工的類別]]・[[純資料類別]]・[[被拒絕的遺贈]]・[[註釋]]

🦨 程式碼壞味道(24) 判斷「哪裡該重構」**

組織函式與變數(8) [[提煉函式]]・[[行內函式]]・[[提煉變數]]・[[行內變數]]・[[改變函式宣告]]・[[封裝變數]]・[[引入參數物件]]・[[拆分階段]]

封裝(7) [[封裝記錄]]・[[封裝集合]]・[[以物件取代基本型別]]・[[以查詢取代暫時變數]]・[[提煉類別]]・[[內聯類別]]・[[隱藏委託關係]]

搬移與迴圈(5) [[搬移函式]]・[[搬移欄位]]・[[拆分迴圈]]・[[以管道取代迴圈]]・[[移除死程式碼]]

簡化條件邏輯(5) [[分解條件式]]・[[合併條件式]]・[[以衛述句取代嵌套條件式]]・[[以多型取代條件式]]・[[引入特例]]

重構 API 與繼承(5) [[將查詢與修改分離]]・[[移除旗標參數]]・[[以子類取代型別碼]]・[[提煉超類]]・[[函式上移]]

🔧 主要重構手法(30) 「怎麼改」**

兩頂帽子 你要嘛在「加功能」、要嘛在「重構」,不要同時戴兩頂帽子。

先重構再加功能 如果加功能很難,先重構到「容易加」,再加。

前提是測試 沒有可靠測試就先補;遺留碼見 [[修改程式碼的藝術]]。

🧭 重構心法