举例讲解设计模式中的访问者模式在Java编程中的运用

 更新时间:2016年05月06日 09:38:51   作者:匆忙拥挤repeat  
这篇文章主要介绍了举例讲解设计模式中的访问者模式在Java编程中的运用,访问者模式是一种将算法与对象结构分离的软件设计模式,需要的朋友可以参考下

访问者(Visitor)模式:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。访问者模式的结构图如下:

20165693247459.png (481×461)

通过上图可以看到他有如下角色:
抽象访问者(Visitor)角色:定义接口,声明一个或多个访问操作。
具体访问者(ConcreteVisitor)角色:实现抽象访问者所声明的接口,也就是抽象访问者所声明的各个访问操作。
抽象元素(Visitable)角色:声明一个接受操作,接受一个访问者对象作为一个参数。
具体元素结点(ConcreteElement)角色:实现抽象结点所规定的接受操作。
数据结构对象(ObjectStructure)角色:可以遍历结构中的所有元素,提供一个接口让访问者对象都可以访问每一个元素。
模拟代码如下:

interface Visitor { 
  void visit(Gladiolus g); 
 
  void visit(Chrysanthemum c); 
} 

// concrete visitor   名称访问 
class StringVisitor implements Visitor { 
  String s; 
 
  public String toString() { 
    return s; 
  } 
 
  public void visit(Gladiolus g) { 
    s = "Gladiolus"; 
  } 
 
  public void visit(Chrysanthemum c) { 
    s = "Chrysanthemum"; 
  } 
} 

 

// concrete visitor   蜜蜂访问 
class BeeVisitor implements Visitor { 
  public void visit(Gladiolus g) { 
    System.out.println("蜜蜂 来 访问 Gladiolus"); 
  } 
 
  public void visit(Chrysanthemum c) { 
    System.out.println("蜜蜂 来 访问 Chrysanthemum"); 
  } 
} 
 
interface Flower { 
  void accept(Visitor v); 
} 

 

/* 
 * concrete element   菊花 
 */ 
class Chrysanthemum implements Flower { 
  public void accept(Visitor v) { 
    v.visit(this); 
  } 
} 

 

// concrete element   剑兰 
class Gladiolus implements Flower { 
  public void accept(Visitor v) { 
    v.visit(this); 
  } 
} 

 

//这是Flower一个对象生成器 
class FlowerGenerator { 
  private static Random rand = new Random(); 
 
  public static Flower newFlower() { 
    switch (rand.nextInt(2)) { 
    default: 
    case 0: 
      return new Gladiolus(); 
    case 1: 
      return new Chrysanthemum(); 
    } 
  } 
} 
public class Test { 
  /* 
   * 首先在客户端先获得一个具体的访问者角色 遍历对象结构 对每一个元素调用accept方法,将具体访问者角色传入 这样就完成了整个过程 
   */ 
  public static void main(String args[]) { 
    List<Flower> flowers = new ArrayList<Flower>(); 
    for (int i = 0; i < 10; i++) 
      flowers.add(FlowerGenerator.newFlower()); 
    Visitor visitor = new StringVisitor(); 
    Iterator<Flower> iterator = flowers.iterator(); 
    while (iterator.hasNext()) { 
      iterator.next().accept(visitor); 
      System.out.println(visitor); 
    } 
    System.out.println("---------------"); 
    /* 
     * 一个新的访问行为 :BeeVisitor 蜜蜂访问 
     */ 
    Visitor visitor2 = new BeeVisitor(); 
    for (Flower flower : flowers) { 
      flower.accept(visitor2); 
    } 
 
  } 
} 

结果:

Gladiolus 
Chrysanthemum 
Chrysanthemum 
Gladiolus 
Chrysanthemum 
Chrysanthemum 
Chrysanthemum 
Chrysanthemum 
Gladiolus 
Gladiolus 
--------------- 
蜜蜂 来 访问 Gladiolus 
蜜蜂 来 访问 Chrysanthemum 
蜜蜂 来 访问 Chrysanthemum 
蜜蜂 来 访问 Gladiolus 
蜜蜂 来 访问 Chrysanthemum 
蜜蜂 来 访问 Chrysanthemum 
蜜蜂 来 访问 Chrysanthemum 
蜜蜂 来 访问 Chrysanthemum 
蜜蜂 来 访问 Gladiolus 
蜜蜂 来 访问 Gladiolus 

有以下情形可以考虑使用访问者模式:

1、一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。Visitor使得你可以将相关的操作集中起来定义在一个类中。
3、当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。
4、 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。
这些个人看来都是建议,项目中还要具体问题具体分析了。
 

相关文章

  • Hadoop源码分析五hdfs架构原理剖析

    Hadoop源码分析五hdfs架构原理剖析

    本篇是Hadoop源码分析系列文章第五篇,主要介绍Hadoop的hdfs架构原理剖析,后续本系列文章会持续更新,有需要的朋友可以借鉴参考下
    2021-09-09
  • java 中Map详解及实例代码

    java 中Map详解及实例代码

    这篇文章主要介绍了java 中Map详解及实例代码的相关资料,需要的朋友可以参考下
    2017-04-04
  • 使用MyBatis-Generator如何自动生成映射文件

    使用MyBatis-Generator如何自动生成映射文件

    这篇文章主要介绍了使用MyBatis-Generator如何自动生成映射文件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • 最新版IDEA配置 Tomcat的详细过程

    最新版IDEA配置 Tomcat的详细过程

    本文介绍如何在IDEA中配置Tomcat服务器,并创建Web项目,首先检查Tomcat是否安装完成,然后在IDEA中创建Web项目并添加Web结构,接着,配置编译输出路径和依赖,将Tomcat的jar包复制到项目中,最后,配置Tomcat服务器并运行项目,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2025-01-01
  • SpringBoot常用计量与bean属性校验和进制数据转换规则全面分析

    SpringBoot常用计量与bean属性校验和进制数据转换规则全面分析

    这篇文章主要介绍了SpringBoot常用计量、bean属性校验与进制数据转换规则,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-10-10
  • Java JDK动态代理在拦截器和声明式接口中的应用小结

    Java JDK动态代理在拦截器和声明式接口中的应用小结

    Java动态代理技术通过反射机制在运行时动态生成代理类,实现对目标对象方法的拦截和增强,本文给大家介绍Java JDK动态代理在拦截器和声明式接口中的应用小结,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • 解决JPA @OneToMany及懒加载无效的问题

    解决JPA @OneToMany及懒加载无效的问题

    这篇文章主要介绍了解决JPA @OneToMany及懒加载无效的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 将Mybatis升级为Mybatis-Plus的详细过程

    将Mybatis升级为Mybatis-Plus的详细过程

    本文详细介绍了在若依管理系统(v3.8.8)中将MyBatis升级为MyBatis-Plus的过程,旨在提升开发效率,通过本文,开发者可实现系统功能无损升级,同时享受MyBatis-Plus带来的便捷特性,如代码简化和性能优化,需要的朋友可以参考下
    2025-04-04
  • 在ssm中使用ModelAndView跳转页面失效的解决

    在ssm中使用ModelAndView跳转页面失效的解决

    这篇文章主要介绍了在ssm中使用ModelAndView跳转页面失效的解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • java实现图片上传至本地实例详解

    java实现图片上传至本地实例详解

    我们给大家分享了关于java实现图片上传至本地的实例以及相关代码,有需要的朋友参考下。
    2018-08-08

最新评论