1.意图:表示一个作用于某对象结构中的各元素的操作。它允许在不改变各元素的类的前提下定义作用于这些元素的操作。
2.结构

Visitor(访问者)为该对象结构中ConcreteElement的每一个类声明一个Visit操作。该操作的名字和特征标识了发送Visit请求给该访问者的那个类,这使得访问者可以确定正被访问元素的具体的类。这样访问者就可以通过该元素的特定接口直接访问它。
ConcreteVisitor(具体访问者)实现每个有Visitor声明的操作,每个操作实现本算法的一部分,而该算法片段乃是对应于结构中对象的类。ConcreteVisitor为该算法提供了上下文并存储它的局部状态。这一状态常常在遍历该结构的过程中累积结果。
Element(元素)定义以一个访问者为参数的Accept操作。
ConcreteElement(具体元素)实现以一个访问者为参数的Accept操作。
ObjectStructure(对象结构)能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个组合或者一个集合,如一个列表或一个无序集合。
3.适用性:
一个对象结构包含很多类对象,它们有不同的接口,而用户想对这些对象实施一些依赖于其具体类的操作。
需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而又想要避免这些操作”污染“这些对象的类。Visitor使得用户可以将相关的操作集中起来定义在一个类中。当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。
定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作比较好。
4.常见案例:累积结果
代码案例
某图书管理系统中管理着两种类型的文献:图书和论文。现在要求统计所有馆藏文献的总页码(假设图书馆中有一本540页的图书和两篇各25页的论文,那么馆藏文献的总页码就是590页)。采用Visitor(访问者)模式实现该要求。
软件设计师考试2015年上半年下午题第6题

interface LibraryVisitor{void visit (Book p_book);void visit (Article p_article);void printSum();
}
class LibrarySumPrintVisitor implements LibraryVisitor{//打印总页数private int sum = 0;@Overridepublic void visit(Book p_book) {sum += p_book.getNumberOfPages();}@Overridepublic void visit(Article p_article) {sum += p_article.getNumberOfPages();}@Overridepublic void printSum() {System.out.println("总页数SUM="+sum);}
}
interface LibraryItemInterface{void accept(LibraryVisitor visitor);
}
class Article implements LibraryItemInterface{private String m_titile;//论文名private String m_author;//论文作者private int m_start_page;private int m_end_page;public Article(String p_author,String p_title,int p_start_page,int p_end_page){m_end_page = p_end_page;m_start_page = p_start_page;m_titile = p_title;m_author = p_author;}public int getNumberOfPages(){return m_end_page - m_start_page;}@Overridepublic void accept(LibraryVisitor visitor) {visitor.visit(this);}
}
class Book implements LibraryItemInterface{private String m_title;//书名private String m_author;//作者private int m_pages;//页数public Book (String p_author,String p_title,int p_pages){m_title = p_title;m_author = p_author;m_pages = p_pages;}public int getNumberOfPages(){return m_pages;}@Overridepublic void accept(LibraryVisitor visitor){visitor.visit(this);}
}
public class Visitor {public static void main(String[] args) {LibraryVisitor visitor = new LibrarySumPrintVisitor();Book b = new Book("张三","掌声在哪里",20);Article a = new Article("李四","历史那些事",20,25);visitor.visit(b);visitor.visit(a);visitor.visit(a);visitor.printSum();}
}

运行结果

访问者模式Visitor相关推荐

  1. 设计模式:访问者模式(Visitor Pattern)

    访问者模式(Visitor Pattern): 封装一些作用于某种数据结构的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作. 主要将数据结构与数据操作分离,解决数据结构和操作 ...

  2. c++访问者模式visitor

    c++访问者模式visitor 概念 角色和职责 优缺点 案例 概念 Visitor模式也叫访问者模式,是行为模式之一,它分离对象的数据和行为,使用Visitor模式,可以不修改已有类的情况下,增加新 ...

  3. 二十四种设计模式:访问者模式(Visitor Pattern)

    访问者模式(Visitor Pattern) 介绍 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 示例 有一个Message实体类,某些对 ...

  4. 设计模式之访问者模式(Visitor)

    访问者模式(Visitor) 在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法.通过这种方式,元素的执行算法可以随着访问者改变而改变 主要将数据结构与 ...

  5. 设计模式之访问者模式(Visitor)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  6. 《研磨设计模式》chap25 访问者模式Visitor(3)联合组合模式+总结

    1. 联合组合模式 //抽象的组件对象,相当于访问者模式中的元素对象 public abstract class Component {//接受访问者的访问 public abstract void ...

  7. 《研磨设计模式》chap25 访问者模式Visitor(2)模式应用到场景

    1. 实现 //各种客户的父类 public abstract class Customer { private String customerId;// 客户编号 private String na ...

  8. 【设计模式】—— 访问者模式Visitor

    对于某个对象或者一组对象,不同的访问者,产生的结果不同,执行操作也不同.此时,就是访问者模式的典型应用了. 应用场景 1 不同的子类,依赖于不同的其他对象 2 需要对一组对象,进行许多不相关的操作,又 ...

  9. 设计模式(17) 访问者模式(VISITOR) C++实现

    意图: 表示一个作用于某对象结构的各元素的操作.它使你可以再不改变各元素的类的前提下定义作用于这些元素的新操作. 动机: 之前在学校的最后一个小项目就是做一个编译器,当时使用的就是访问者模式. 在静态 ...

  10. [设计模式] 23 访问者模式 visitor Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对访问者模式是这样说的:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.访问 ...

最新文章

  1. ElasticSearch实战:Linux日志对接Kibana
  2. 自定义图片字段调用的问题出现{dede:img ..}
  3. 十天学会AngularJS之02
  4. 一个小爱好竟然改变了全世界!Linux30年都经历了什么?
  5. hadoop+lucene+web 综合小demo
  6. PHP分批次处理数据
  7. AlphaGo Zero代码迟迟不开源,TF等不及自己推了一个
  8. MySQL客户端工具的选择
  9. Windows界面UI自绘编程(上)之下部
  10. 微信公众号群发模板消息占用每月4次群发次数吗
  11. 【HTML 教程系列第 9 篇】什么是 HTML 中的换行标签 br
  12. STM32F7+STM32CubeMX5.21+SD+FATFS
  13. 微信小程序—页面内分享按钮用图标代替
  14. 服务器SN信息,命令查看服务器SN号
  15. niushop多商户商户端手机uniapp源码v4单商户v4_Saas开源版含uniapp以及niushop社区团购标准版源码开源的区别
  16. 明日传奇第三季/全集Legends of Tomorrow迅雷下载
  17. 骨传导蓝牙耳机排行榜、精选五款骨传导耳机品牌推荐
  18. nus计算机和iss学院,走进新加坡国立大学系统科学院
  19. Embeded linux之网卡驱动
  20. *2-2 OJ 1163 导弹拦截之测试版

热门文章

  1. HDFS RBF(基于路由的federation)的全局配额管理方案
  2. echarts 修改tooltip字体大小
  3. 有趣的SQL DIGEST
  4. AdaBoost算法-课堂笔记
  5. vue中使用echarts结合百度地图制作地图(引入百度地图、获取百度地图实例、设置百度地图)
  6. layer 弹出层传递参数
  7. 理解事务四大特性(Transaction)——原子性、一致性、隔离性和持久性(ACID)
  8. 探索浏览器(二)向DNS服务器查询Web服务器的IP地址
  9. Java中文生僻字排序
  10. LoadRunner 11(LR11) 下载链接及破解方法