🎯 什麼情境該想到我

當你「有一個由多種元素組成、而且結構相對穩定的物件結構,卻常常要對它新增各種操作」的時候(例如在語法樹 AST 上跑多種分析、對一批元素做多種匯出格式),又不想每加一種操作就去改每個元素類別,想把這些操作集中管理。

⚙️ 怎麼用(步驟 / 公式)

意圖:表示一個作用於某物件結構中各元素的操作。訪問者讓你可以在不改變各元素類別的前提下,定義作用於這些元素的新操作。

主要參與者 / 結構:

  • Visitor(訪問者介面):對每一種具體元素宣告一個 visitXxx(element)
  • ConcreteVisitor(具體訪問者):一種操作=一個訪問者,實作對各元素的處理。
  • Element(元素介面):宣告 accept(visitor)
  • ConcreteElement(具體元素)accept() 內回呼 visitor.visitXxx(this)
  • ObjectStructure(物件結構):能列舉其元素,讓訪問者逐一造訪。

做法要點:

  1. 每個元素實作 accept(visitor),在裡面呼叫 visitor 對應自己型別的方法(double dispatch,雙重分派)。
  2. 想新增一種操作,就寫一個新的具體訪問者,完全不動元素類別。
  3. 走訪物件結構,對每個元素呼叫 accept(),把操作邏輯集中在訪問者裡。

🧪 我實際套用的紀錄

  • (待填)

⚠️ 注意 / 什麼時候不適用

  • 元素類別若常常增減就不適用:每加一種新元素,所有訪問者都得改(加一個 visitXxx)。
  • 為了讓訪問者拿到需要的資料,元素往往得多開放內部,容易破壞封裝。
  • 只有一兩種操作、或結構還不穩定時,直接把方法寫在元素類別上更簡單。

🔗 相關工具