Visitor模式的簡單實現

[size=x-large]1.描述[/size]
一個集合中有同一種類型的數據,他們或者繼承同一個父類,或者實現了同一個接口,但是他們各自的屬性和方法有時卻存在着差異,而這些數據一旦被添加進一些集合以後,他們的差異性就被一般化了,若需要再次取得這些具有“個性”的類的話,則要做大量如下的工作:

for(A a : collection){
if(a instance of B){
//.....
}else if(a instance of C){
//.....
}else ....
}

這樣的代碼就顯得異常的繁瑣,Visitor模式實際上就是在做與if else 相同的工作,但是他的代碼更加飄逸一點。

[size=x-large]2.接口定義[/size]
兩個主要接口:
~Visitor

public interface Visitor {

public void visit(StringElement s);

public void visit(IntElement n);

public void visit(DoubleElement d);

}

Visitor定義了不同類型的對象的訪問方法


~Visitable

public interface Visitable {

public void accept(Visitor visitor);

}

Visitable定義的是被訪問者接受訪問者(也就是實現了visitor)訪問的方法,如果實現visitable的對象accept了一個visitor對象,那麼visitable就會調用visitor中相應的visit的方法(通過函數重載來實現),做到對visitable內所有可被訪問的元素(同樣也是實現了visitable)的遍歷。(這話說的.....有點繞了...)

[size=x-large]3.具體實現類的函數定義如下:[/size]
三個實現了visitable接口的元素類:

public class IntElement implements Visitable{

private int value = 1;

public int getValue(){
return this.value;
}

public void accept(Visitor visitor) {
visitor.visit(this);
}

}

public class DoubleElement implements Visitable{

private double value = 1.1;

public double getValue(){
return this.value;
}

public void accept(Visitor visitor) {
visitor.visit(this);
}

}




public class StringElement implements Visitable{

private String value = "I'm String";

public String getValue(){
return this.value;
}

public void accept(Visitor visitor) {
visitor.visit(this);
}
}


同樣是實現了visitable的集合類,visitor對象被這個集合類accept後,visitor便可以以各自的方法來訪問這個集合中那些有“個性”的元素了

public class Elements implements Visitable{


private Collection<Visitable> col = new ArrayList();

public void addElement(Visitable v){
col.add(v);
}

public void accept(Visitor visitor) {
for(Visitable v : col){
v.accept(visitor);
}
}
}


主函數

public static void main(String args[]){
Elements es = new Elements();
es.addElement(new StringElement());
es.addElement(new IntElement());
es.addElement(new DoubleElement());
MyVisitor mv = new MyVisitor();
es.accept(mv);
}


運行結果:

element.StringElement:I'm String
element.IntElement:1
element.DoubleElement:1.1


先傳個uml圖上來,畫得有點難看而且又點不規範,但是大概的模型就是這樣的

[img]http://dl.iteye.com/upload/attachment/454090/88f370a2-7494-35c6-8da0-95cfc21cecf3.jpg[/img]

[size=x-large]4.寫在後面:[/size]
剛開始接觸到visitor模式時,的確有點不懂,後來是用到dom4j的時候,在解析xml文件時,發現dom4j對其提供的visitor模式支持非常好用,只需要創建一個visitor了實現類,給它幾個篩選條件,我就能從一個Element中獲得我想要的節點信息了,這是纔對visitor模式有了一個大概的瞭解。不懂沒關係,敲一敲就會明白的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章