問題領域 vs 解決方案領域命名 (Problem vs Solution Domain Names)

★★★★Draft

FromClean Code

📚 From the Books

問題領域 vs 解決方案領域命名 (Problem vs Solution Domain Names)Naming

好名字不只要揭露意圖,還要用讀者「已經懂」的詞彙來揭露。讀程式的人不該在腦中把你的名字翻譯成他們熟悉的概念——那次翻譯就是純粹的認知損耗。關鍵抉擇是:這個名字該借用解決方案領域(工程師的語言:演算法、設計模式、CS 術語),還是問題領域(領域專家的語言:業務概念)?答案取決於誰會來讀它。

🧠 Why It Matters

NOTE

判準很簡單:若沒有更貼切的問題領域名字,就用解決方案領域的名字。 因為看程式碼的人終究是程式設計師;當某個東西沒有專門的業務術語,工程師熟悉的技術詞(設計模式、演算法名)就是最不需要翻譯的選擇。

⚖️ Case Study

購物車 — 泛用容器名藏起了業務意義
// data / insert:偏解決方案領域,但只講「這是個容器」
class Cart {
  constructor() {
    this.data = []; // 泛用的資料容器,看不出裝什麼
  }

  insert(product) {
    this.data.push(product);
  }
}

data 只說「這裡有一堆資料」,insert 只說「往容器塞東西」。對一個購物車來說,這兩個名字借的是通用資料結構的詞,卻沒有回答最重要的問題:裝的是什麼?這在做什麼業務動作?讀者得自己補上「喔,這是商品、這是加入購物車」。

購物車 — 問題領域名把業務意義寫進來
// products / addProduct:問題領域,直接說出商業意義
class Cart {
  constructor() {
    this.products = []; // 明確指出裝的是商品
  }

  addProduct(product) {
    this.products.push(product);
  }
}

同樣一段邏輯,換成 productsaddProduct 之後,名字自己就說清楚了「這是商品清單、這是把商品加進購物車」。購物車是個業務概念,讀它的人關心的是商業意義而非容器機制——所以問題領域的詞彙勝出。

工程機制 — 這裡反而該用解決方案領域名
// 一個排程元件,讀它的只有工程師:用工程術語最不需要翻譯
class JobQueue {
  constructor() {
    this.pendingJobs = [];
  }

  enqueue(job) {
    this.pendingJobs.push(job);
  }

  dequeue() {
    return this.pendingJobs.shift();
  }
}

這裡沒有現成的業務術語可借,而且會來讀它的清一色是程式設計師。JobQueueenqueuedequeue 借用的是每個工程師都懂的資料結構語言——硬套一個委婉的業務名反而讓熟悉 queue 的人多繞一圈。沒有更貼切的問題領域名字時,解決方案領域的名字就是正解。

TIP

先問「誰會來讀這段程式、他腦中已經有哪套詞彙」。答案是業務/領域專家,就往問題領域挑名字(PremiumPolicy);答案是工程師、或這根本是純技術機制,就大方用解決方案領域的名字(OrderObserverJobQueue)。目標始終一致:讓讀者不必翻譯。

WARNING

別為了「看起來專業」就把明明有業務名字的東西硬包成技術術語——把購物車的 products 改叫 data,等於丟掉現成的問題領域詞彙,逼每個讀者重新推敲它裝什麼。泛用名不是中立,是把意義的成本轉嫁給讀者。

🔑 Takeaways

✍️ My Notes

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

📖 Further Reading