- 表示一个作用于某对象结构中的个元素的操作。使得可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
1.定义
表示一个作用于某对象结构中各个元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
2.基础代码
这里使用访问者模式的前提是Element的子类稳定,比如人类只有男女两类,否则Visitor中的抽象方法就不再稳定了。
(1)visitor类
package designmode.visitor;
public abstract class Visitor {
//为ConcreteElement的每个类声明一个visit操作
public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA);
public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB);
}
(2)Convretevisitor类
package designmode.visitor;
public class ConcreteVisitor1 extends Visitor{
@Override
public void VisitConcreteElementA(ConcreteElementA concreteElementA) {
System.out.println("ConcreteElementA被Concretevisitor1访问");
}
@Override
public void VisitConcreteElementB(ConcreteElementB concreteElementB) {
System.out.println("ConcreteElementB被Concretevisitor1访问");
}
}
package designmode.visitor;
public class ConcreteVisitor2 extends Visitor{
@Override
public void VisitConcreteElementA(ConcreteElementA concreteElementA) {
System.out.println("ConcreteElementA被Concretevisitor2访问");
}
@Override
public void VisitConcreteElementB(ConcreteElementB concreteElementB) {
System.out.println("ConcreteElementB被Concretevisitor2访问");
}
}
(3)Element类
package designmode.visitor;
public abstract class Element {
public abstract void Accept(Visitor visitor);
}
(4)ConcreteElement类
package designmode.visitor;
public class ConcreteElementA extends Element{
@Override
public void Accept(Visitor visitor) {
visitor.VisitConcreteElementA(this); //双向委派
}
public void OperationA(){ } //其他相关方法
}
package designmode.visitor;
public class ConcreteElementB extends Element{
@Override
public void Accept(Visitor visitor) {
visitor.VisitConcreteElementB(this);
}
public void OperationB(){
}
}
(5)ObjectStructure类
package designmode.visitor;
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 e : elements){
e.Accept(visitor);
}
}
}
(6)client类
package designmode.visitor;
public class Client {
public static void main(String[] args) {
ObjectStructure o=new ObjectStructure();
o.attach(new ConcreteElementA());
o.attach(new ConcreteElementB());
ConcreteVisitor1 v1=new ConcreteVisitor1();
ConcreteVisitor2 v2=new ConcreteVisitor2();
o.Accept(v1);
o.Accept(v2);
}
}
3.应用场景
-
访问者模式适用于数据结构相对稳定的系统
-
把数据结构(人)和作用域结构上的操作(状态)之间的耦合解脱开,使得操作集合可以相对自由地演化。
-
目的
把处理从数据结构分离出来。
很多系统可以按照算法和数据结构分开,如果这样地系统有比较稳定地数据结构,又有易于变化的算法的话,使用访问者模式比较合适。因为访问者模式使得算法操作的增加变得容易。
-
优点
增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者,访问者模式将有关行为(不同的对象的)集中到一个访问者对象中
-
缺点
访问者的缺点其实也就是使新增加数据结构变得困难。
因为很难找到数据结构不变化的情况,所以用访问者模式的机会不太多。