訊息鏈與中間人 (Message Chains & Middle Man)

★★★★★Draft

FromRefactoring

📚 From the Books

訊息鏈與中間人 (Message Chains & Middle Man)Code Smells

這是一對互相拉扯的味道。Message Chains 是層層呼叫如 a.getB().getC().getD(),呼叫端被綁死在物件的內部結構上;解法是隱藏委託或把這段導航抽成函式。但一旦委託藏過頭,某個類別過半函式都只是把呼叫轉手給別人,就變成 Middle Man(不必要的傳話);解法反過來——移除中間人,直接溝通。兩個修法方向相反,拿捏之間才是重點。

🧠 Why It's a Problem

NOTE

修法會互相拉扯:對訊息鏈用「隱藏委託」會多加轉手方法,過頭就長出中間人;對中間人「移除中間人」讓呼叫端直接對話,過頭又長回訊息鏈。目標不是站到某一端,而是找到平衡點。

⚖️ Refactoring

訊息鏈 → 隱藏委託(或把導航抽成函式);中間人 → 移除中間人,直接溝通。

Message Chains — 前:一路 get 下去
// 呼叫端被綁在整條結構上:manager 藏在 department 裡,department 藏在 person 裡
const manager = person.getDepartment().getManager();

呼叫端得知道 person → department → manager 這條路;department 只是被穿過去的中繼站。

Message Chains — 後:隱藏委託
class Person {
  // 讓 Person 代為轉交,呼叫端不再看見 department
  getManager() {
    return this.department.getManager();
  }
}

const manager = person.getManager();

呼叫端只跟 person 打交道,中間的結構被藏起來,改變 department 不再波及呼叫端。

Middle Man — 前:過半函式只是轉手
class Person {
  // 這些方法本身沒做事,只是把呼叫轉交給 department
  getManager() {
    return this.department.getManager();
  }
  getChargeCode() {
    return this.department.getChargeCode();
  }
}

隱藏委託加得太多,Person 淪為只會傳話的中間人。

Middle Man — 後:移除中間人,直接溝通
// 讓呼叫端直接對真正做事的物件說話
const manager = person.department.getManager();

拿掉空轉的轉手方法,呼叫端直接與 department 溝通。

TIP

同一組物件,兩個修法把你推向相反方向。判斷依據不是規則,而是:轉手方法有沒有帶來封裝的價值?沒有就是中間人,收掉它;有就留著擋住訊息鏈。

🔑 Takeaways

✍️ My Notes

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

📖 Further Reading

🔗 Dive Deeper