一、定义
访问者模式表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下作用于这些元素的新操作。
二、框架运用
JDK中的FileVisitor,Spring中的BeanDefinitionVisitor
三、实战
1、visitor
public interface Visitor {
void visitConcreteElementA(ConcreteElementA concreteElementA);
void visitConcreteElementB(ConcreteElementB concreteElementB);
}
public class ConcreteVisitorA implements Visitor {
@Override
public void visitConcreteElementA(ConcreteElementA concreteElementA) {
System.out.println("ConcreteVisitorA ConcreteElementA 被访问");
}
@Override
public void visitConcreteElementB(ConcreteElementB concreteElementB) {
System.out.println("ConcreteVisitorA ConcreteElementB 被访问");
}
}
public class ConcreteVisitorB implements Visitor {
@Override
public void visitConcreteElementA(ConcreteElementA concreteElementA) {
System.out.println("ConcreteVisitorB ConcreteElementA 被访问");
}
@Override
public void visitConcreteElementB(ConcreteElementB concreteElementB) {
System.out.println("ConcreteVisitorB ConcreteElementB 被访问");
}
}
2、element
public interface Element {
void accept(Visitor visitor);
}
public class ConcreteElementA implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visitConcreteElementA(this);
}
}
public class ConcreteElementB implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visitConcreteElementB(this);
}
}
3、管理类
public class ObjectStructure {
private List<Element> elementList = new ArrayList<>();
public void add(Element element){
elementList.add(element);
}
public void remove(Element element){
elementList.remove(element);
}
public void accept(Visitor visitor){
elementList.forEach(e->e.accept(visitor));
}
}
4、运行和结果
public class Client {
public static void main(String[] args) {
ObjectStructure structure = new ObjectStructure();
Element elementA = new ConcreteElementA();
Element elementB = new ConcreteElementB();
Visitor visitorA = new ConcreteVisitorA();
Visitor visitorB = new ConcreteVisitorB();
structure.add(elementA);
structure.add(elementB);
structure.accept(visitorA);
structure.accept(visitorB);
}
}
Connected to the target VM, address: '127.0.0.1:63240', transport: 'socket'
ConcreteVisitorA ConcreteElementA 被访问
ConcreteVisitorA ConcreteElementB 被访问
ConcreteVisitorB ConcreteElementA 被访问
ConcreteVisitorB ConcreteElementB 被访问
Disconnected from the target VM, address: '127.0.0.1:63240', transport: 'socket'