学习访问者模式,因为这个是ASM的使用的核心思想,ASM通过提供各种visitor去完成对方法,成员变量,类,注解等的修改和扩展,这种访问者方式和正式的有些区别,这个就是类,方法,成员变量,注解等是被动的提供了访问,我们插入对应的字节码。
wiki上面介绍访问者模式,是一种正宗的访问者,但是我们日常code的时候可能需要像ASM那样对这个做一个灵活变通,有时候,变通才能更好的写出自己的合适代码,实现自己的想法。
示例Java代码如下:
interface Visitor {
// 访问者接口,实现这个接口就可以访问对应的角色,这里就是轮子、引擎、车体、整车。
void visit(Wheel wheel);
void visit(Engine engine);
void visit(Body body);
void visit(Car car);
}
// 下面对应的四个角色都提供accept方法,在方法里实现让visitor去访问自己,然后对应的方法就可以被访问者访问了,这里的也满足了通过方法访问对应的变量的方式
class Wheel {
private String name;
Wheel(String name) {
this.name = name;
}
String getName() {
return this.name;
}
void accept(Visitor visitor) {
visitor.visit(this);
}
}
class Engine {
private int sudu = 0;
int getSudu() {
return sudu;
}
void addSudu() {
sudu ++;
}
void removeSudu() {
if (sudu > 0) {
sudu --;
}
}
void accept(Visitor visitor) {
visitor.visit(this);
}
}
class Body {
void accept(Visitor visitor) {
visitor.visit(this);
}
}
class Car {
private Engine engine = new Engine();
private Body body = new Body();
private Wheel[] wheels
= { new Wheel("front left"), new Wheel("front right"),
new Wheel("back left") , new Wheel("back right") };
// 这个类里面的accept方法去整合别的模块被访问的方式。
void accept(Visitor visitor) {
visitor.visit(this);
engine.accept(visitor);
body.accept(visitor);
for (int i = 0; i < wheels.length; ++ i)
wheels[i].accept(visitor);
}
}
class PrintVisitor implements Visitor {
// 具体的访问方法,不同的访问者可能有自己的特色访问方式,用自己的
public void visit(Wheel wheel) {
System.out.println("Visiting " + wheel.getName()
+ " wheel");
}
public void visit(Engine engine) {
// 这里就是访问到之后可以修改他的状态,例如asm里面就是增加字节码或者获取对应的属性啥的
engine.addSudu();
System.out.println("Visiting engine sudu is : " + engine.getSudu());
engine.addSudu();
System.out.println("Visiting engine sudu is : " + engine.getSudu());
engine.addSudu();
System.out.println("Visiting engine sudu is : " + engine.getSudu());
engine.removeSudu();
System.out.println("Visiting engine sudu is : " + engine.getSudu());
}
public void visit(Body body) {
System.out.println("Visiting body");
}
public void visit(Car car) {
System.out.println("Visiting car");
}
}
// 访问者模式,就是被访问者接受访问者的访问,访问者可以访问对应被访问者的数据
public class StudyVistor {
public static void main(String[] args) {
Car car = new Car();
Visitor visitor = new PrintVisitor();
car.accept(visitor);
}
}
访问者模式的使用场景 1.对象结构比较稳定,但经常需要在此对象结构上定义新的操作。 2.需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。