核心觀點#
在軟體開發中,命名(Naming)不僅僅是給變數代號,
它深刻影響程式碼的可讀性(Readability)與可維護性(Maintainability)。
一個好名稱應能清晰表達該變數、函式或類別的內容與目的。
好命名能讓閱讀程式碼的人像讀文章一樣順暢;糟糕命名則會製造理解障礙,甚至引發誤解。
程式碼主要是寫給「人」看的,其次才是給機器執行。
選擇好名稱的關鍵,在於具備優良的描述技巧與建立團隊共通的文化背景。
命名的基本原則#
1. 讓名稱代表意圖 (Use Intention-Revealing Names)#
名稱如果需要註解補充說明,就代表它已經失敗。
名稱本身就該回答:它為什麼存在?做什麼事?怎麼被使用?
# Bad Naming: 需要去推測 d 是什麼
def d(s):
...
# Good Naming: 直接看出是根據速度計算距離
def calculate_distance(speed):
...2. 避免誤導 (Avoid Disinformation)#
程式設計師應避免留下掩蓋程式碼本意的錯誤線索。
- 避免用專有名詞作為變數名: 如
hp,aix,sco,除非真的與該平台有關,否則容易混淆 - 小心用資料結構關鍵字: 除非該變數真的是 List,否則別用
accountList
(改用accounts或accountGroup),以免誤導開發者以為它是特定型別。 - 避免過於相似名稱: 如
ProductInfo與ProductData,這兩者語意幾乎沒差,讀者無法區分具體用途
無效資訊的陷阱:用
a1, a2, ... aN這種數列命名法完全無法提供任何有意義線索。
此外,若變數Name已夠清晰,就不需改成NameString,除非要特別強調它是非直覺型別。
考量人類的認知習慣#
1. 名稱應易於朗誦 (Pronounceable Names)#
寫程式是項社交活動。如果變數名稱唸不出來,在 Code Review 或討論時就會非常尷尬且難以溝通。
# Bad Naming: 像是密碼,難以在口頭討論中提及
def calc_avg_grd(s_grds):
...
# Good Naming: 清晰、像自然的語句
def calculate_average_grade(student_grades):
...2. 名稱應易於搜尋 (Searchable Names)#
單一字母的變數名(如 e)或魔術數字(Magic Numbers),在大型專案中極難被精確定位。
長度與視野成正比:變數的有效範圍(Scope)越大,名稱就應越長、越具描述性
取代魔術數字:
# Bad: 數字 7 的意義不明,且很難搜尋(文中太多 7) if count % 7: ... # Good: 定義常數,易於修改且語意清晰 MAX_CLASSES_PER_STUDENT = 7 if count % MAX_CLASSES_PER_STUDENT: ...
減少雜訊與思維轉換#
1. 減少多餘資訊#
| 命名壞習慣 | 現代專業做法 | 原因 |
|---|---|---|
| 型別編碼 (Type Encoding) | 移除 str,i_,list_ 等前綴 | IDE 可顯示型別, 前綴增加維護成本 |
成員變數前綴 (m_) | 直接用變數名(或透過 this. 區分) | m_ 是視覺雜訊,IDE 已用顏色區分 |
介面前綴 (I 開頭) | 用簡潔介面名,將裝飾留給實作類別 | 使用者應關注抽象, 非實作細節 |
2. 避免思維轉換 (Map to Mental Models)#
讀者不該在閱讀時還需在腦中將你的變數「翻譯」成他們熟知概念。請選擇對方熟悉術語:
降低認知負擔:精準的術語選擇#
| 讀者與情境 | Domain | 命名範例 |
|---|---|---|
| 針對程式設計師 | Solution Domain | UserBuffer, JobQueue, OrderObserver |
| 針對業務/領域專家 | Problem Domain | PremiumPolicy, EscrowLedger, ClaimVoucher |
Solution Domain 使用工程師熟悉的術語(演算法、設計模式);
Problem Domain 使用領域專家的語言,確保技術實現與商業需求對齊。
範例:解決方案領域 vs 問題領域
情境:購物車設計
Solution Domain (給工程師看): 強調資料結構
class Cart: def __init__(self): self.data = [] # 泛用的資料容器 def insert(self, product): self.data.append(product)Problem Domain (給業務邏輯看): 強調業務意義
class Cart: def __init__(self): self.products = [] # 明確指出是商品 def add_product(self, product): self.products.append(product)
結構與語法的一致性#
1. 概念一致性 (Pick One Word per Concept)#
不要讓 controller、manager、driver 同時混雜在專案中代表類似概念。
這會讓人困惑 DeviceManager 和 ProtocolController 到底有什麼本質差別。
請選定一個詞,然後貫徹到底。
2. 詞性選擇#
| 元素類型 | 建議詞性 |
|---|---|
| 類別 (Class) / 物件 (Object) | 名詞或名詞片語 |
| 方法 (Method) | 動詞或動詞片語 |
3. 上下文的拿捏 (Context)#
添加有意義的上下文: 變數名若過於簡單,可放入適當函式或類別中賦予意義,或透過命名補充。
# 修正前:CarInfo 類別內的變數重複 car_ 字首
class CarInfo:
def get_car_speed(self):
return self.car_speed
# 修正後:移除贅字,因為 reader 已經知道這是 Car 的方法
class Car:
def get_speed(self):
return self.speed