訪問者模式(Visitor Pattern)是一種將數據操作與數據結構分離的設計模式。這種模式適用于數據結構相對穩定,而操作算法經常改變的情況。訪問者模式將數據結構(穩定的部分)中的元素(Element)的訪問行為(變化的部分)封裝在一個獨立的訪問者(Visitor)類中,使得可以在不修改數據結構的前提下增加新的操作。
訪問者模式包含以下幾個角色:
-
Visitor(訪問者):接口聲明了一個或多個訪問操作,每個操作對應數據結構中的一種可能元素類型。
-
ConcreteVisitor(具體訪問者):實現Visitor接口,為每個Element類提供一個訪問操作實現,該操作會執行相應的業務邏輯。
-
Element(元素):接口或抽象類,定義了一個接受訪問者(accept)的方法,該方法通常以訪問者作為參數。
-
ConcreteElement(具體元素):實現了Element接口或繼承了Element抽象類,實現了accept()方法,該方法通常調用訪問者的訪問操作并傳入自己作為參數。
-
ObjectStructure(對象結構):是元素的集合,它可以是組合模式的結構、數組或其他數據結構。它提供一種讓訪問者可以訪問其所有元素的能力,如可以遍歷所有元素并調用元素的accept()方法。
以下是訪問者模式的一個簡單Java代碼示例:
// 訪問者接口
public interface Visitor {void visit(ConcreteElementA element);void visit(ConcreteElementB element);
}// 具體訪問者
public class ConcreteVisitor implements Visitor {@Overridepublic void visit(ConcreteElementA element) {System.out.println("Visiting ConcreteElementA: " + element.operationA());}@Overridepublic void visit(ConcreteElementB element) {System.out.println("Visiting ConcreteElementB: " + element.operationB());}
}// 元素接口
public interface Element {void accept(Visitor visitor);
}// 具體元素A
public class ConcreteElementA implements Element {@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}public String operationA() {return "ConcreteElementA";}
}// 具體元素B
public class ConcreteElementB implements Element {@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}public String operationB() {return "ConcreteElementB";}
}// 對象結構示例(這里使用簡單的集合)
import java.util.ArrayList;
import java.util.List;public class ObjectStructure {private List<Element> elements = new ArrayList<>();public void attach(Element element) {elements.add(element);}public void detach(Element element) {elements.remove(element);}public void accept(Visitor visitor) {for (Element element : elements) {element.accept(visitor);}}
}// 客戶端代碼
public class Client {public static void main(String[] args) {ObjectStructure os = new ObjectStructure();os.attach(new ConcreteElementA());os.attach(new ConcreteElementB());Visitor visitor = new ConcreteVisitor();os.accept(visitor);}
}
在上面的示例中,ConcreteVisitor
實現了Visitor
接口,并為每種類型的Element
提供了訪問方法。ConcreteElementA
和ConcreteElementB
實現了Element
接口,并實現了accept
方法以接受訪問者。ObjectStructure
作為元素的集合,它允許訪問者訪問其所有元素。客戶端代碼創建了ObjectStructure
實例,并添加了一些Element
實例,然后創建了一個Visitor
實例,并讓ObjectStructure
接受這個Visitor
。這樣,Visitor
就能夠訪問所有的Element
實例,并執行相應的操作。