先寫註解 (Write the Comments First)

★★★★★Draft

FromA Philosophy of Software Design

📚 From the Books

先寫註解 (Write the Comments First)Comments & Formatting

多數人把寫註解拖到最後——編碼與測試都做完才補。這幾乎保證寫出爛文件。真正的時機是一開始:在動手寫程式碼之前,先為類別與方法寫下介面註解。這麼做不只讓文件更好,更關鍵的是——它把註解變成一種設計工具,讓你在寫下任何實作前就審視自己的抽象。

🧠 為什麼先寫

IMPORTANT

「先寫註解」最重要的好處不是文件,而是改善系統設計。註解在這裡的角色是設計的鏡子:你對某個抽象描述得越吃力,就越說明這個抽象本身有問題。

⚖️ 把註解當設計步驟

作者的流程是:新類別先寫類別介面註解;再寫最重要 public 方法的介面註解與簽章(主體留空);在這些註解之間反覆迭代,直到結構大致對勁;接著才填入方法主體。程式碼完成時,註解就完成了——永遠不會有「待寫文件」的積欠

先寫介面註解(主體留空),拿它來審視抽象
// 先寫下這個抽象「對外承諾什麼」,此時一行實作都還沒有。
// 目標:用最少的字,完整而清楚地描述介面。

/**
 * 一個容量固定的環狀緩衝區:寫滿後,新資料覆蓋最舊的資料。
 * 讀取一律從最舊到最新。此類別不做同步,呼叫端自行負責。
 */
class RingBuffer {
  /** 建立一個最多容納 capacity 筆元素的緩衝區。 */
  constructor(capacity) {}

  /** 加入一筆元素;若已滿,則覆蓋最舊的一筆。 */
  push(item) {}

  /** 回傳目前所有元素,由最舊到最新。 */
  toArray() {}
}

寫完這幾行你就能先問:這個介面描述得簡短又完整嗎?若是,代表介面簡單、抽象乾淨——現在才動手寫主體。

紅旗:註解怎麼寫都又臭又長 → 抽象有問題
/**
 * 加入一筆元素。若尚未滿就直接放到尾端;若已滿而且 overwrite 為
 * true 就覆蓋最舊那筆並移動 head;若已滿而 overwrite 為 false 就
 * 丟出例外,但如果同時 grow 為 true 則改為擴充容量再放入,擴充時
 * 舊資料的順序要依 head 位置重新排列……
 */
push(item, overwrite, grow) {}

註解必須寫得又長又複雜才描述得完,就是設計出問題的訊號:這個方法把太多決策塞進一個介面。這正是「難以描述(Hard to Describe)」的紅旗——註解在這裡扮演複雜性的煤礦坑金絲雀。修法不是把註解寫短,而是回頭把抽象拆乾淨,讓每個方法都能用一句簡單完整的話說清楚。

CAUTION

註解只有在它完整且清楚時才是複雜性的好指標。一段殘缺或晦澀的註解無法拿來衡量抽象的深淺——先把它寫到位,再用它來評斷設計。

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading