本文共 2727 字,大约阅读时间需要 9 分钟。
访问者模式是一种软件设计模式,其核心思想是通过封装操作,实现对数据结构的灵活扩展。这种模式在软件开发中广泛应用,尤其是在需要对已有代码库进行扩展时,能够有效避免对原有代码的修改。
访问者模式的核心思想是:在不改变数据结构的前提下,定义新的操作。具体而言,访问者模式通过定义一个接口(Visitor),将对数据结构中各元素的操作封装进去。这样,系统的核心逻辑可以保持不变,而新增的功能可以通过实现不同的访问者类来实现。
以科学家接受采访的情景为例:访谈流程是固定的,包括三个部分:学校经历、工作经历和科研成果。但不同记者的采访内容会有所不同。这种变化可以通过访问者模式实现:定义一个Visitor接口,分别在每个访问者类中实现对应的采访方法。
###Visitor接口Visitor接口定义了所有可能的访问操作。例如:
public interface Visitor { void askSchoolExperience(String name); void askWorkExperience(String name); void askScienceAchievement(String name);}
###具体访问者类每个具体的访问者类实现Visitor接口,定义自己的访问逻辑。例如,新华社的记者可能更关心科研成果,而青年报的记者可能更关注精神层面的东西。
public class XinhuaVisitor implements Visitor { @Override public void askSchoolExperience(String name) { System.out.println("请问" + name + ":在学校取得的最大成就是什么?"); } //其他方法类似...}
###被访问者类被访问者类(Element)通过一个accept方法接收访问者对象。例如,科学家的类可以有一个accept方法,将访问者传递给内部逻辑。
public class Scientist { private Visitor visitor; private String name; public Scientist(String name) { this.name = name; } public void accept(Visitor visitor) { this.visitor = visitor; } public void interview() { visitor.askSchoolExperience(name); visitor.askWorkExperience(name); visitor.askScienceAchievement(name); }}
###访问过程通过上述实现,可以看到访问者模式的核心逻辑:访问者通过interface定义了操作,具体访问者实现这些操作,被访问者通过accept方法将访问者接收进来,最后在interview方法中调用访问者的操作。
这种设计使得访谈流程固定不变,而采访内容的变化可以通过不同的访问者实现。
###文件树遍历在JDK中,FileVisitor接口定义了文件遍历的操作。不同的遍历器可以实现不同的操作,比如统计文件数或打印文件名。
public interface FileVisitor { FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs); FileVisitResult visitFile(T file, BasicFileAttributes attrs); FileVisitResult postVisitDirectory(T dir, IOException exc);}
###字节码修改(ASM)ASM框架中的ClassVisitor类通过继承FileVisitor接口,实现了对字节码的修改。ClassReader类作为被访问者,负责读取和解析字节码。
public class ClassReader { public ClassReader(byte[] classfile) { //解析字节码并存储为Class对象 } public ClassVisitor accept(ClassVisitor visitor) { //调用visitor的各个方法 visitor.visitClass(...); return visitor; }}
ClassWriter类则是ClassVisitor的实现类,负责输出修改后的字节码。
public class ClassWriter implements ClassVisitor { public ClassWriter(ClassVisitor visitor) { //初始化 } @Override public ClassVisitor visitClass(...) { //修改字节码 return this; } //其他方法类似...}
这种设计使得字节码的修改与原有框架无关,提高了扩展性。
访问者模式在以下场景下表现出色:
###优点
###缺点
访问者模式是一种强大的设计模式,其核心在于通过抽象化的接口实现灵活的扩展。如果你的项目需要对已有代码进行扩展,而无需频繁修改核心逻辑,那么访问者模式绝对值得考虑。
转载地址:http://riakz.baihongyu.com/