Visitor
定義
作用於某個物件群中各個物件的操作。
它可以使你在不改變這些物件本身的情況下
,
定義作用於這些物件的新操作。
在 Java 中 ,Visitor 模式實際上是分離了 collection 結構中的元素和對這些元素進行操作的行爲。
爲何使用
Visitor?
Java
的
Collection(
包括
Vector
和
Hashtable)
是我們最經常使用的技術
,
可是
Collection
好象是個黑色大染缸
,
本來有各種鮮明類型特徵的物件一旦放入後
,
再取出時
,
這些類型就消失了。那麽我們勢必要用
If
來判斷
,
如
:
Iterator iterator = collection.iterator()
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof Collection)
messyPrintCollection((Collection)o);
else if (o instanceof String)
System.out.println("'"+o.toString()+"'");
else if (o instanceof Float)
System.out.println(o.toString()+"f");
else
System.out.println(o.toString());
}
在上例中
,
我們使用了
instanceof
來判斷
o
的類型。
很顯然 , 這樣做的缺點代碼 If else if 很繁瑣。我們就可以使用 Visitor 模式解決它。
如何使用
Visitor?
針對上例
,
我們設計一個介面
visitor
訪問者
:
public interface Visitor |
在這個介面中 , 將我們認爲 Collection 有可能的類別的類型放入其中。
有了訪問者 , 我們需要被訪問者 , 被訪問者就是我們 Collection 的每個元素 Element, 我們要爲這些 Element 定義一個可以接受訪問的介面 ( 訪問和被訪問是互動的 , 只有訪問者 , 被訪問者如果表示不歡迎 , 訪問者就不能訪問 ),
我們定義這個介面叫 Visitable, 用來定義一個 Accept 操作 , 也就是說讓 Collection 每個元素具備可訪問性。
public interface Visitable |
好了 , 有了兩個介面 , 我們就要定義他們的具體實現 (Concrete class):
public class ConcreteElement implements Visitable |
再看看訪問者的 Concrete 實現 :
public class ConcreteVisitor implements Visitor { // 在本方法中 , 我們實現了對 Collection 的元素的成功訪問 public void visitCollection(Collection collection) { Iterator iterator = collection.iterator() while (iterator.hasNext()) { Object o = iterator.next(); if (o instanceof Visitable) ((Visitable)o).accept(this); }
public void visitString(String string) {
public void visitFloat(Float float) { ? |
在上面的 visitCollection 我們實現了對 Collection 每個元素訪問 , 只使用了一個判斷語句 , 只要判斷其是否可以訪問。
至此 , 我們完成了 Visitor 模式基本架構。
使用
Visitor
模式的前提
物件群結構中
(Collection)
中的物件類型很少改變
,
也就是說訪問者的身份類型很少改變
,
如上面中
Visitor
中的類型很少改變
,
如果需要增加新的操作
,
比如上例中我們在
ConcreteElement
具體實現外
,
還需要新的
ConcreteElement2 ConcreteElement3
。
可見使用 Visitor 模式是有前提的 , 在兩個介面 Visitor 和 Visitable 中 , 確保 Visitor 很少變化 , 變化的是 Visitable, 這樣使用 Visitor 最方便。
如果 Visitor 也經常變化 , 也就是說 , 物件群中的物件類型經常改變 , 一般建議是 , 不如在這些物件類別中逐個定義操作。但是 Java 的 Reflect 技術解決了這個問題。
Reflect 技術是在運行期間動態獲取物件類型和方法的一種技術 ,