一、前言
我們在項目開發中,訪問者模式的使用還是比較少的。訪問者模式主要是爲了將數據結構和數據操作做分離。所以我們在使用這種設計模式的時候常常會要求我們的數據結構不要輕易做出改變,它主要是我瞭解決穩定的數據結構和易變的操作耦合問題。
二、訪問者模式
概述:表示一個作用於某對象結構中的各元素的操作。 它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。
使用場景:
1.一個對象結構包含很多類對象,它們有不同的接口,而你想對這些對象實施一些依賴於其具體類的操作。
2.需要對一個對象結構中的對象進行很多不同的並且不相關的操作,而你想避免讓這些操作“污染”這些對象的類。 Visitor使得你可以將相關的操作集中起來定義在一個類中。 當該對象結構被很多應用共享時,用Visitor模式讓每個應用僅包含需要用到的操作。
3.定義對象結構的類很少改變,但經常需要在此結構上定義新的操作。 改變對象結構類需要重定義對所有訪問者的接口,這可能需要很大的代價。 如果對象結構類經常改變,那麼可能還是在這些類中定義這些操作較好。
優點: 1、符合單一職責原則。 2、優秀的擴展性。 3、靈活性。
缺點: 1、具體元素對訪問者公佈細節,違反了迪米特原則。 2、具體元素變更比較困難。 3、違反了依賴倒置原則,依賴了具體類,沒有依賴抽象。
三、代碼展示
3.1 定義一個訪問接口,該接口訪問不同的元素
public interface Visitor {
public void visitString(StringElement stringE);
public void visitFloat(FloatElement floatE);
public void visitCollection(Collection collection);
}
3.2 定義訪問元素的接口,該接口有一個接受訪問的行爲,參數是訪問者接口
public interface Visitable {
public void accept(Visitor visitor);
}
3.3 訪問者實現類
public class ConcreteVisitor implements Visitor {
public void visitCollection(Collection collection) {
// TODO Auto-generated method stub
Iterator iterator = collection.iterator();
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof Visitable) {
((Visitable)o).accept(this);
}
}
}
public void visitFloat(FloatElement floatE) {
System.out.println(floatE.getFe());
}
public void visitString(StringElement stringE) {
System.out.println(stringE.getSe());
}
}
3.4 訪問元素實現類
public class FloatElement implements Visitable {
private Float fe;
public FloatElement(Float fe) {
this.fe = fe;
}
public Float getFe() {
return this.fe;
}
public void accept(Visitor visitor) {
visitor.visitFloat(this);
}
}
public class StringElement implements Visitable {
private String se;
public StringElement(String se) {
this.se = se;
}
public String getSe() {
return this.se;
}
public void accept(Visitor visitor) {
visitor.visitString(this);
}
}
3.4 測試結果
public class Test {
public static void main(String[] args) {
Visitor visitor = new ConcreteVisitor();
StringElement se = new StringElement("abc");
se.accept(visitor);
FloatElement fe = new FloatElement(new Float(1.5));
fe.accept(visitor);
System.out.println("===========");
List result = new ArrayList();
result.add(new StringElement("abc"));
result.add(new StringElement("abc"));
result.add(new StringElement("abc"));
result.add(new FloatElement(new Float(1.5)));
result.add(new FloatElement(new Float(1.5)));
result.add(new FloatElement(new Float(1.5)));
visitor.visitCollection(result);
}
}
abc
1.5
===========
abc
abc
abc
1.5
1.5
1.5