Visitor 訪問者模式
Visitor模式:
提供一個作用於某對象結構中的各元素的操作表示,它使我們可以在不改變各元素的類的前提下定義作用於這些元素的新操作。
訪問者模式是一種將算法與對象結構分離的軟件設計模式。訪問者模式是一種對象行爲型模式。結構圖:
示例類圖:
示例代碼:
// Visitor
public interface ComputerPartVisitor {
public void visit(Computer computer);
public void visit(Mouse mouse);
public void visit(Keyboard keyboard);
public void visit(Monitor monitor);
}
// ConcreteVisitor
public class ComputerPartDisplayVisitor implements ComputerPartVisitor {
@Override
public void visit(Computer computer) {
System.out.println("Displaying " + computer.getPart());
}
@Override
public void visit(Mouse mouse) {
System.out.println("Displaying " + mouse.getPart());
}
@Override
public void visit(Keyboard keyboard) {
System.out.println("Displaying " + keyboard.getPart());
}
@Override
public void visit(Monitor monitor) {
System.out.println("Displaying " + monitor.getPart());
}
}
// Element
public abstract class ComputerPart {
protected String part;
public ComputerPart(String part) {
this.part = part;
}
public abstract void accept(ComputerPartVisitor computerPartVisitor);
public String getPart() {
return part;
}
}
// ConcreteElement
public class Keyboard extends ComputerPart {
public Keyboard(String part) {
super(part);
}
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Monitor extends ComputerPart {
public Monitor(String part) {
super(part);
}
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Mouse extends ComputerPart {
public Mouse(String part) {
super(part);
}
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
// ObjectStructure
public class Computer extends ComputerPart {
private ComputerPart[] parts;
public Computer(String part) {
super(part);
this.parts = new ComputerPart[] { new Mouse("Mouse"), new Keyboard("Keyboard"), new Monitor("Monitor") };
}
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
for (int i = 0; i < parts.length; i++) {
parts[i].accept(computerPartVisitor);
}
computerPartVisitor.visit(this);
}
}
// 測試
public class VisitorTest {
public static void main(String[] args) {
ComputerPart computer = new Computer("Computer");
ComputerPartVisitor visitor = new ComputerPartDisplayVisitor();
computer.accept(visitor);
}
}
角色:
Vistor(抽象訪問者):
抽象訪問者爲對象結構中每一個具體元素類ConcreteElement聲明一個訪問操作,
從這個操作的名稱或參數類型可以清楚知道需要訪問的具體元素的類型,具體訪問者需要實現這些操作方法,定義對這些元素的訪問操作。ConcreteVisitor(具體訪問者):
具體訪問者實現了每個由抽象訪問者聲明的操作,每一個操作用於訪問對象結構中一種類型的元素。Element(抽象元素):
抽象元素一般是抽象類或者接口,它定義一個accept()方法,該方法通常以一個抽象訪問者作爲參數。ConcreteElement(具體元素):
具體元素實現了accept()方法,在accept()方法中調用訪問者的訪問方法以便完成對一個元素的操作。ObjectStructure(對象結構):
對象結構是一個元素的集合,它用於存放元素對象,並且提供了遍歷其內部元素的方法。它可以結合組合模式來實現,
也可以是一個簡單的集合對象,如一個List對象或一個Set對象。
缺點:
增加新的元素類很困難,在訪問者模式中,每增加一個新的元素類都意味着要在抽象訪問者角色中增加一個新的抽象操作,
並在每一個具體訪問者類中增加相應的具體操作,違背了“開閉原則”的要求。破壞封裝,當採用訪問者模式的時候,就會打破組合類的封裝。