訪問者模式(Visitor)官硝,表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作矗蕊。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。
訪問者模式適用于數(shù)據(jù)結(jié)構(gòu)相對(duì)穩(wěn)定的系統(tǒng)泛源,它把數(shù)據(jù)結(jié)構(gòu)和作用于數(shù)據(jù)結(jié)構(gòu)上的操作之間的耦合解脫開拔妥,使得操作集合可以相對(duì)自由地演化。
訪問者模式的目的是要把處理從數(shù)據(jù)結(jié)構(gòu)分離出來达箍。
有比較穩(wěn)定的數(shù)據(jù)結(jié)構(gòu)没龙,又有易于變化的算法的話,使用訪問者模式就意味著增加一個(gè)新的訪問者缎玫。訪問者模式將有關(guān)的行為集中到一個(gè)訪問者對(duì)象中硬纤。
缺點(diǎn):使增加新的數(shù)據(jù)結(jié)構(gòu)變得困難
主方法
public class main {
public static void main(String[] args) {
ObjectStructure o = new ObjectStructure();
o.attach(new ConcreteElementA());
o.attach(new ConcreteElementB());
VisitorImpl1 v1 = new VisitorImpl1();
VisitorImpl2 v2 = new VisitorImpl2();
o.accept(v1);
o.accept(v2);
}
}
元素抽象類
/**
* 定義一個(gè)accept操作,接受對(duì)象為訪問者
*/
public abstract class Element {
public abstract void accept(Visitor visitor);
}
元素實(shí)現(xiàn)類1
public class ConcreteElementA extends Element {
public void accept(Visitor visitor) {
visitor.visitConcreteElementA(this);
}
public void operationA() {
}
}
元素實(shí)現(xiàn)類2
public class ConcreteElementB extends Element {
public void accept(Visitor visitor) {
visitor.visitConcreteElementB(this);
}
public void operationB() {
}
}
訪問者抽象類
/**
* 訪問者抽象類赃磨,該對(duì)象為ConcreteElement每個(gè)類聲明一個(gè)visit操作
*/
public abstract class Visitor {
public abstract void visitConcreteElementA(ConcreteElementA concreteElementA);
public abstract void visitConcreteElementB(ConcreteElementB concreteElementB);
}
訪問者實(shí)現(xiàn)類1
/**
* 具體訪問者1筝家,實(shí)現(xiàn)每個(gè)由visitor聲明的操作,每個(gè)操作實(shí)現(xiàn)算法的一部分邻辉,而該算法片斷乃是對(duì)應(yīng)于結(jié)構(gòu)中對(duì)象的類
*/
public class VisitorImpl1 extends Visitor {
public void visitConcreteElementA(ConcreteElementA concreteElementA) {
System.out.println(String.format("{%s}被{%s}訪問", concreteElementA.getClass().getName(), this.getClass().getName()));
}
public void visitConcreteElementB(ConcreteElementB concreteElementB) {
System.out.println(String.format("{%s}被{%s}訪問", concreteElementB.getClass().getName(), this.getClass().getName()));
}
}
訪問者實(shí)現(xiàn)類2
/**
* 具體訪問者2溪王,實(shí)現(xiàn)每個(gè)由visitor聲明的操作,每個(gè)操作實(shí)現(xiàn)算法的一部分值骇,而該算法片斷乃是對(duì)應(yīng)于結(jié)構(gòu)中對(duì)象的類
*/
public class VisitorImpl2 extends Visitor {
public void visitConcreteElementA(ConcreteElementA concreteElementA) {
System.out.println(String.format("{%s}被{%s}訪問", concreteElementA.getClass().getName(), this.getClass().getName()));
}
public void visitConcreteElementB(ConcreteElementB concreteElementB) {
System.out.println(String.format("{%s}被{%s}訪問", concreteElementB.getClass().getName(), this.getClass().getName()));
}
}
對(duì)象結(jié)構(gòu)類莹菱,能夠枚舉數(shù)據(jù)結(jié)構(gòu)中的元素,可以提供一個(gè)高層的接口以允許訪問者訪問他的元素
import java.util.ArrayList;
import java.util.List;
/**
* 能枚舉它的元素吱瘩,可以提供一個(gè)高層接口以允許訪問者訪問它的元素
*/
public class ObjectStructure {
private List<Element> elements = new ArrayList<Element>();
public void attach(Element element) {
elements.add(element);
}
public void detach(Element element) {
elements.remove(element);
}
public void accept(Visitor visitor) {
for (Element e : elements) {
e.accept(visitor);
}
}
}