iT邦幫忙

2025 iThome 鐵人賽

DAY 21
0
Software Development

消除你程式碼的臭味系列 第 21

Day 21- 註解:讓程式碼自己說話

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20250903/20124462P1N8QjGguI.png

消除你程式碼的臭味 Day 21- 註解:讓程式碼自己說話

好的程式碼不需要註解,因為程式碼本身就能被讀懂。

程式碼本身,才是唯一的、絕對的事實來源
註解不是。

註解充其量只是一個旁觀者的論述,它會過期、會腐爛、會跟不上程式碼的變化,最後,它會說謊騙你

一個撒謊的註解,比沒有註解要壞上一萬倍。
它會主動地誤導下一個讀程式碼的人,把他們引導到錯誤的理解上,進而製造出更隱晦
的臭味 bug。

把時間花在改進命名與結構,而不是寫註解。

經典案例:用註解掩蓋爛命名

浪費時間寫註解,卻不願意花半秒鐘去想一個好名字。

// 🔴 臭味:這段註解的存在,就是為了掩蓋命名的懶惰。
// 計算稅金
function c(p) { 
  return a * 0.05; 
}
// 🔴 臭味:甚至忘了更新註解
// 金額乘以 5% 的稅率
function c(p) { 
  return amount * 0.05; 
}

https://ithelp.ithome.com.tw/upload/images/20250922/20124462xGQB3UUgKV.png

用命名消除註解的需求

// 🟢 好味道:不需要任何註解。命名清晰。

const SALE_TAX_RATE = 0.07;

function calculateAmountWithTax(amount) {
  return amount * (1 + SALE_TAX_RATE);
}

https://ithelp.ithome.com.tw/upload/images/20250922/20124462gGNfkepeDB.png

  • 程式碼即文件: calculateAmountWithTaxSALE_TAX_RATE 這些名字,已經把你要知道的事情都告訴你了。它清楚、準確、不會說謊誤導你。

  • 投資報酬率: 花在想一個好名字上的 10 秒鐘,會在未來幾年裡,為每一個讀這段程式碼的人省下無數的時間和精力。花在寫一段爛註解上的 5 秒鐘,則是在為未來製造技術債。

什麼時候要下註解?

註解是個必要的惡,只能在特殊情況下使用。
一個好的註解,永遠不解釋「做了什麼 What」,只解釋「為什麼這麼做 Why」。

  1. 反直覺程式碼,要解釋「為什麼」這麼奇怪: 因為某些外部原因(比如要繞過某個瀏覽器 bug 或硬體缺陷)而寫得非常違反直覺時,你必須寫註解。否則,可能下一個工程師會「修正」你這段看起來很蠢的正確程式碼,然後毀掉一切。

    // 好註解:解釋「為什麼」
    // 底下的位移操作看起來很怪,但這是為了相容舊版的 XYZ 晶片。
    // 詳見硬體手冊第 253 頁。
    value = (value << 1) | (value >> 31);
    
  2. 提供背景脈絡: 註解可以連結到外部的規格文件、研究論文、或 issue tracker。它為程式碼提供了它本身無法承載的背景故事。

# 好註解:提供背景
# 這裡的演算法實作了 Knuth-Morris-Pratt 演算法。
# 關於 KMP 的詳細解釋,請參考:[論文連結]
def kmp_search(text, pattern):
    # ...

避免的註解

  • 直接翻譯程式碼的註解。
  • 大段過期的註解,與實作脫節。
  • 用註解關掉 linter 或測試而不處理根因。

如果你看到這些註解,就代表程式碼發臭了。

  • 殭屍程式碼 (Zombie Code)

    // const oldLogic = a * b;
    const newLogic = a + b;
    

    為什麼要留下那段被註解掉的程式碼?是還在用嗎?
    版本控制系統就是為此而生的。
    如果你真的需要找回舊程式碼,去 git log 裡找。

  • 空頭支票 (Empty Promises):

    // TODO: 之後要來重構這裡
    

    TODO 註解通常是都不會實現。
    如果這件事真的「TO DO」,那就去 issue tracker 開一張票。
    如果不是,那就現在修好它,或者刪掉它。

比註解更好的東西:Git 歷史紀錄

一個好的 Commit Message (提交訊息),遠比程式碼裡的註解更有價值。
它在一個更高的維度上解釋了「為什麼」。

  • 爛的 Commit Message: fix bug
  • 好的 Commit Message:
    fix(API): 修正 calculateTax 在 amount 為 null 時的崩潰問題
    
    之前的實作沒有處理 amount 為 null 的邊界情況,會導致
    TypeError。
    
    此修改在函式開頭加入了一個保護式敘述 (guard clause),
    若 amount 為 null 或 undefined,直接回傳 0。
    這符合 spec 文件 v1.2 中定義的稅務計算規則。
    
    相關 Ticket: #451

這份提交訊息,很好解釋了what, why, how,而且它被永久地記錄在版本歷史裡,不會像程式碼裡的註解一樣過期。

除臭準則

  • 你的第一選擇永遠是重構。

  • 你的第二選擇是重命名。

  • 你的最後、最不情願的選擇,才是寫註解。

今日重點

  • 先讓程式碼可讀,再考慮註解。
  • 記錄「為什麼」,別複述「做什麼」。
  • 讓命名、結構與版本歷史記錄成為最好的文件。

讓程式碼自己說話、註解只補充關鍵背景,這就是在消除你程式碼的臭味。


上一篇
Day 20- 依賴注入:鬆開那個耦合
系列文
消除你程式碼的臭味21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言