作者探討重構四大面向:定義(What)、效益(Why)、時機(When)以及執行者與相關議題(Who)。
重構不僅是修改程式碼,更是種維持軟體生命力的核心紀律。
mindmap
root((重構原則))
What 定義
名詞:結構調整
動詞:手法應用
核心:不改變外在行為
Why 效益
改善架構設計
提高可理解性
幫助找出 Bug
提高開發速度
When 時機
三次法則
預備性重構
理解性重構
撿垃圾式重構
Who 挑戰
團隊協作
Code Review
CI/CD 整合什麼是重構 (Definition)#
作者將「重構」分為名詞與動詞兩層次定義,強調其核心在於不改變外在行為。
| 定義類型 | 說明 |
|---|---|
| 名詞 | 不改變軟體可觀察行為的前提下,變動內部,以提高可理解性並降低修改成本 |
| 動詞 | 使用一系列特定重構手法,重新架構軟體 |
重構過程中,不應同時加入新功能。
重構與開發新功能應視為兩頂不同帽子,時刻區分清楚。
flowchart LR
subgraph hat1 ["🎩 重構帽"]
R1[調整結構] --> R2[不加新功能]
R2 --> R3[保持行為不變]
end
subgraph hat2 ["🧢 功能帽"]
F1[新增功能] --> F2[不改結構]
F2 --> F3[專注業務邏輯]
end
hat1 <-->|切換| hat2為何需要重構 (Why)#
重構並非無謂的浪費時間,而是為了長遠的開發效率。
| 效益 | 說明 |
|---|---|
| 改善架構設計 | 抵抗架構劣化 (Entropy),保持系統健康 |
| 提高可理解性 | 讓程式碼實際行為與開發者預期保持一致 |
| 幫助找出 Bug | 深入理解結構、釐清假設,讓隱藏 Bug 浮現 |
| 提高開發速度 | 模組化設計讓開發者只需理解局部即可修改 |

Design Stamina Hypothesis — cumulative functionality over time with poor design

Design Stamina Hypothesis — good design vs. poor design
何時該重構 (When)#
重構不應被視為專案結束後的「清理階段」,而應隨時隨地發生。
flowchart TD
Start([開始工作]) --> Q1{要新增功能?}
Q1 -->|是| Q2{現有結構<br/>支援嗎?}
Q2 -->|否| P["🔧 預備性重構<br/>Preparatory"]
Q2 -->|是| Dev[開發新功能]
P --> Dev
Q1 -->|否| Q3{理解程式碼?}
Q3 -->|困難| C["📖 理解性重構<br/>Comprehension"]
Q3 -->|是| Q4{看到壞味道?}
Q4 -->|是| L["🗑️ 撿垃圾式重構<br/>Litter-Pickup"]
Q4 -->|否| Done([繼續工作])
C --> Done
L --> Done
Dev --> Done| 策略 | 時機 | 做法 |
|---|---|---|
| 三次法則 (Rule of Three) | 重複程式碼第三次出現 | 進行抽象化,避免 DRY 違規 |
| 預備性重構 (Preparatory) | 新增功能之前 | 先調整結構,讓修改變容易 |
| 理解性重構 (Comprehension) | 遇到難懂的舊程式碼 | 透過重構釐清邏輯 |
| 撿垃圾式重構 (Litter-Pickup) | 隨時隨地 | 看到糟糕結構就隨手清理 |
| 伺機性重構 (Opportunistic) | 開發過程中 | 與當前工作一同進行 |
| 長時程重構 (Long-Term) | 大型架構調整 | 每當觸碰相關區域就改善一點 |
重構的難題與應對 (Challenges)#
導入重構時,團隊往往會面臨技術與管理上的挑戰。Code Review 是推廣重構的好時機。
如果你先重構程式碼,往往能給出更具體、優質的建議,而不僅是指出問題。
如何應對重構的五大難題
⚠️ 重構的常見挑戰與應對策略
| 挑戰 | 應對策略 |
|---|---|
| 減慢開發速度 | 長期來看重構提升速度,現狀往往是重構「過少」而非「過度」 |
| 缺乏程式碼擁有權 | 保留舊介面並標註 Deprecated,讓呼叫端有時間遷移 |
| 分支合併衝突 | 實施 CI,頻繁合併主幹,防止分支差異過大 |
| 缺乏自我測試 | 建立自動化測試作為安全網 |
| 處理老舊程式碼 | 尋找接縫 (Seams) 插入測試,逐步建立信心圈 |
| 資料庫重構 | 使用遷移腳本管理 Schema 變更,支援多版本並行 |
關於品質與速度:
- 小步驟是關鍵: 透過極小步驟重構,能讓你快速寫出好程式,
且因每次變動極小,幾乎不需時間除錯- 優秀程式碼更需重構: 為保持優秀的設計與適應性,優秀程式碼也需經歷大量重構