訪問者模式 Visitor Pattern

Bear熊
4 min readJun 10, 2020

--

書中一開始舉例類似

男人及女人兩個Class去繼承這個 「人」Class的Class

然後他們彼此會說一些話

像是 成功的男人 說 .... 成功的女人說...(性別不同會說不一樣

或是 失敗的男人說***失敗的女人說*** (性別不同惠說不一樣

還有戀愛..(下略

一開始的做法是在男人及女人的Class裡面直接寫 if else 判斷式

class 男人
if ( action == "成功"){ ... }
else if ( action == "失敗" ) { ... }
...
class 女人
if ( action == "成功"){ ... }
else if ( action == "失敗" ) { ... }
...

但是如果這樣未來如果增加 “結婚”這個狀態,就必須要在兩個性別的Class中分別修改。

所以把這個 "成功", "失敗", "結婚", "戀愛" 拆分出來

abstract class Action{
public abstract void GetManReaction(Man m);
public abstract void GetWomanReaction(Woman m);
}
class Success : Action{
public override void GetManReaction(Man m){ ... }
public override void GetWomanReaction(Woman m){ ... }
}
-----以上是狀態相關範例abstract class Person{
public abstract void Accept(Action visitor);
}
class Man : Person{
public override void Accept(Action visitor){ visitor.GetManReaction(this)
};
}
------以上是Person範例

實際應用時會先有一個"List"把所有男人女人儲存在其中,可能用一個Display來顯示有關於不同狀態間的反應。下例子中就是ObjectStructure

ObjectStructure o = new ObjectStructure();
o.Attach(new Man);
o.Attach(new Woman);
Success v1 = new Success();
// ObjectStructure 會去traversal 所有person 並call Accept
o.Display(v1);

所以當增加 "婚姻" 狀態時只需要

class 婚姻: Action{
public override void GetManReaction(Man m){ ... }
public override void GetWomanReaction(Woman m){ ... }
}
---呼叫端只要
婚姻 v2 = new 婚姻();
o.Display(v2);

有提到說此 訪問者模式 為 GoF書中最複雜的一個模式。

訪問者模式( Visitor ),表示一個作用於某物件結構中的各元素之操作。它使你可以再不改變各元素之類別的前提之下,定義作用於這些元素的新操作。

大話設計模式

以上是結構圖

書中提到適用此模式的系統為

資料結構相對穩定的系統,因為他把資料結構和作用於結構上的操作分開之間的耦合關係分開,使得操作可以自由化。

目的要把"處理"從資料結構拉出來

所以如果系統有 穩定的資料結構,又有益於變化的演算法的話,使用此模式是適合的。

優點:增加新的操作很容易,因為增加新的操作意味著增加一個新的訪問者。

缺點:增加新的資料結構便困難

大多時候你並不需要訪問者模式,但當你一但需要訪問者模式時,那就是真的需要他了--GoF四人中其中一人提出此心得

書中談論到上述這句話時說:因為你很難找到不變化的資料結構,此例子中是因為男人女人是不會變化的。而且也很難會新增加類別。

--

--