博客
关于我
大白话聊访问者模式:从入门到实践
阅读量:416 次
发布时间:2019-03-06

本文共 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;    }        //其他方法类似...}

这种设计使得字节码的修改与原有框架无关,提高了扩展性。

当然使用访问者模式

访问者模式在以下场景下表现出色:

  • 需要对已有代码库进行扩展,而无需修改原有代码。
  • 需要支持多种操作,但核心逻辑保持不变。
  • 需要通过参数传递状态或行为,但不想改变已有结构。
  • ###优点

  • 高可维护性:固定不变的逻辑只需修改访问者类。
  • 灵活扩展性:新增功能只需添加新的访问者类。
  • 减少耦合度:减少被访问者与访问者之间的依赖。
  • ###缺点

  • 增加了复杂性:引入多个类需要更多的管理。
  • 被访问者难以扩展:一旦被访问者结构固定,修改难度大。
  • 参考资料

  • 《设计模式》
  • JDK的FileVisitor接口
  • ASM框架文档
  • 访问者模式是一种强大的设计模式,其核心在于通过抽象化的接口实现灵活的扩展。如果你的项目需要对已有代码进行扩展,而无需频繁修改核心逻辑,那么访问者模式绝对值得考虑。

    转载地址:http://riakz.baihongyu.com/

    你可能感兴趣的文章
    Mtab书签导航程序 LinkStore/getIcon SQL注入漏洞复现
    查看>>
    myeclipse配置springmvc教程
    查看>>
    MyEclipse配置SVN
    查看>>
    MTCNN 人脸检测
    查看>>
    MyEcplise中SpringBoot怎样定制启动banner?
    查看>>
    MyPython
    查看>>
    MTD技术介绍
    查看>>
    MySQL
    查看>>
    MySQL
    查看>>
    mysql
    查看>>
    MTK Android 如何获取系统权限
    查看>>
    MySQL - 4种基本索引、聚簇索引和非聚索引、索引失效情况、SQL 优化
    查看>>
    MySQL - ERROR 1406
    查看>>
    mysql - 视图
    查看>>
    MySQL - 解读MySQL事务与锁机制
    查看>>
    MTTR、MTBF、MTTF的大白话理解
    查看>>
    mt_rand
    查看>>
    mysql -存储过程
    查看>>
    mysql /*! 50100 ... */ 条件编译
    查看>>
    mudbox卸载/完美解决安装失败/如何彻底卸载清除干净mudbox各种残留注册表和文件的方法...
    查看>>