
技術債管理:什麼時候該還、什麼時候該借
技術債跟財務債一樣:有計畫地借是槓桿,無意識地借是災難。
先搞清楚什麼是技術債
Ward Cunningham 最早提出「技術債」的比喻時,他的意思是:
「把不夠完善的程式碼發布出去,就像借了一筆債。只要你後來重構把它還清,利息是可以承受的。危險的是你不還,利息(開發速度下降)會慢慢壓垮你。」
但「技術債」這個詞後來被濫用了。不是所有的爛 code 都叫技術債:
| 類型 | 這叫什麼 | 怎麼處理 |
|---|---|---|
| 趕時間所以沒寫測試 | 有意識的技術債 | 記下來,排進後續 sprint |
| 用了已知不完美的架構去快速驗證市場 | 策略性技術債 | 驗證成功後立刻還 |
| 不知道有更好的做法 | 無意識的技術債 | 透過 code review 和學習來預防 |
| 偷懶或缺乏紀律 | 不是技術債,是品質問題 | 改善工程文化和標準 |
關鍵區分: 技術債是「明知有更好的做法,但有意識地選擇快速方案」。如果你不知道有更好的做法,那不是債,是認知盲區。
技術債的利息長什麼樣
財務債的利息是錢,技術債的利息是時間和風險:
借債時省下的時間
↓
┌─────────┐
每次改動 │ 技術債 │ 每次改動
多花的 │ │ 多花的
時間 │ │ 時間
└─────────┘
↓
當利息 > 本金時
你就開始虧了
利息的具體形式:
- 改動成本增加 — 本來改一個欄位 5 分鐘,因為耦合嚴重要改 10 個檔案花 2 小時
- Bug 率上升 — 每次改動都怕壞其他東西,因為沒有測試保護
- 新人上手變慢 — 「這段 code 為什麼這樣寫?」「不知道,別碰它。」
- 信心下降 — 團隊開始害怕改東西,能繞就繞,惡性循環
- 機會成本 — 想加新功能但架構撐不住,被迫先重構
技術債的四象限
Martin Fowler 提出的分類方式,幫你判斷你面對的是哪種債:
有意識的 無意識的
┌──────────────────┬──────────────────┐
│ │ │
│ 「我們知道這樣 │ 「什麼是 │
魯 │ 不好,但趕時間 │ Dependency │
莽 │ 先這樣」 │ Injection?」 │
的 │ │ │
│ → 記錄 + 排期還 │ → 需要學習 │
├──────────────────┼──────────────────┤
│ │ │
│ 「先發布收集回饋 │ 「用了一年才發現 │
謹 │ 再來優化架構」 │ 這個模式更適合」 │
慎 │ │ │
的 │ → 策略正確 │ → 無法避免 │
│ │ │
└──────────────────┴──────────────────┘
左下角(謹慎 + 有意識)是好的技術債:你知道自己在做什麼,有計畫要還。
右上角(魯莽 + 無意識)是最危險的:你不知道自己在欠債,等發現時利息已經很高了。
什麼時候該借技術債
不是所有技術債都該避免。有些場景下,借債是正確的策略:
| 場景 | 借債的理由 | 前提 |
|---|---|---|
| MVP / 市場驗證 | 快速上線比完美架構更重要 | 你有計畫驗證後重構 |
| Deadline 壓力 | 晚一天上線會損失具體的商業價值 | 你記錄了欠的債並排期還 |
| 技術探索 | 不確定最好的做法,先做一個版本 | 你願意在學到更好做法後重寫 |
| 短期專案 | 專案生命週期只有三個月 | 你確定它真的只活三個月 |
不該借的情況:
- 「反正沒人會看這段 code」— 永遠有人會看,通常是三個月後的你
- 「先 work 就好」但沒有「之後怎麼辦」的計畫
- 已經在高利息的 code 上繼續疊加
什麼時候該還技術債
訊號偵測 — 這些跡象代表利息太高了:
- 改動恐懼 — 團隊說「別碰那塊」或「這很危險」
- 相同的 bug 反覆出現 — 修了 A 壞了 B,修了 B 壞了 C
- 新功能開發速度明顯下降 — 本來一週能做的,現在要兩週
- 新人要花超過兩週才能做第一個 PR — 代表 codebase 太難理解
- 你在 workaround 上面疊 workaround — 說明根本問題沒解決
還債的時機點(在這些時候嵌入重構最自然):
- 做新功能的時候 — 「Boy Scout Rule」:離開時比到達時乾淨一點
- 修 bug 的時候 — 修完 bug 順便把周圍的壞味道處理掉
- Sprint planning 時保留 20% 的容量 — 不是整個 sprint 都在還債,而是持續小額還款
- 大版本之間 — 趁 feature freeze 的空檔做結構性重構
技術債追蹤系統
最簡單可行的做法:
## Tech Debt Registry
### TD-001: 使用者驗證沒有 rate limiting
- **位置**: auth/login.ts
- **影響**: 暴力破解風險、每次改 auth 要額外注意
- **利息**: 中(每次安全 review 都會被提出來)
- **還債成本**: 0.5 天
- **優先序**: P1
### TD-002: Order model 沒有狀態機
- **位置**: models/order.ts
- **影響**: 狀態轉換靠 if-else,已經有三次因為狀態錯誤出 bug
- **利息**: 高(每次改訂單流程都很怕)
- **還債成本**: 2 天
- **優先序**: P0不需要華麗的工具。一個 markdown 檔案、一個 Notion 頁面、或是 GitHub Issues 加上 tech-debt label 就夠了。
重點是:讓技術債可見。 看不見的債最危險。
還債策略
| 策略 | 做法 | 適合場景 |
|---|---|---|
| 持續小額還款 | 每個 PR 順手改善一點(Boy Scout Rule) | 日常開發,低風險 |
| 專項還債 Sprint | 整個 sprint 只做重構 | 利息已經高到影響開發速度 |
| Strangler Fig | 新功能用新架構,舊功能逐步遷移 | 大型架構重構 |
| Feature Flag 漸進替換 | 新舊邏輯並行,確認沒問題再切換 | 核心業務邏輯重構 |
| 寫測試先行 | 先補測試,再改結構 | 沒有測試覆蓋的遺留代碼 |
最常見的錯誤:想一次還清所有債。 大型重構風險極高,通常建議用 Strangler Fig 模式漸進替換。
跟非技術人員溝通技術債
PM 或老闆問:「為什麼要花時間重構?功能不是好好的嗎?」
不要說:
- 「code 太醜了」(他不在乎)
- 「架構需要改善」(太抽象)
要說:
- 「現在加一個功能要 3 天,如果重構這塊,以後每個功能只要 1 天」
- 「這個區域每個月平均出 2 個 bug,重構後可以降到接近 0」
- 「新人上手這塊要 2 週,重構後只要 3 天」
用數字和商業影響來說話,不要用技術術語。
反思問題
- 你的專案裡,哪三塊 code 改動時你最害怕? 那就是利息最高的技術債。
- 你有記錄技術債的習慣嗎? 還是都存在腦子裡,換一個人就沒人知道了?
- 你上次「有意識地借技術債」是什麼時候? 你後來有還嗎?
- 你能跟 PM 用一句話解釋為什麼這次要花時間重構嗎?
延伸閱讀
- Code Review 方法論 — Review 時識別技術債的好時機
- 取捨決策框架 — 借債還是還債的決策方法
- 功能從需求到上線 — 在哪些階段容易產生技術債
- Release 方法論 — Feature Freeze 時適合還債