访问者模式Visitor

news2025/1/11 8:48:51

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;
    @Override
    public void visit(Book p_book) {
        sum += p_book.getNumberOfPages();
    }
    @Override
    public void visit(Article p_article) {
        sum += p_article.getNumberOfPages();
    }
    @Override
    public 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;
    }
    @Override
    public 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;
    }
    @Override
    public 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();
    }
}

运行结果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/143754.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

本地机器 Google Colab 通过 SSH 连接远程服务器

1. 情景描述 我自己笔记本配置太垃圾,想要用学校的深度学习服务器在Colab上跑程序。 2. 环境描述 远程服务器 (Ubuntu): 用pip安装 jupyter notebook 以及 jupyter_http_over_ws 拓展包 (前提有python环境和pip) pip install notebookpip install j…

Android设计模式详解之外观模式

前言 外观模式也称门面模式,在开发过程中的运用频率非常高; 定义:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行;门面模式提供一个高层次的接口,使得子系统更易于使用; 使用场景&#…

6.3 Docker

目录 6.3.1 Docker概述 6.3.1.1 什么是Docker 6.3.1.2 Docker组成 6.3.2 Docker的安装 6.3.2.1 下载Docker依赖的环境 6.3.2.2 指定Docker镜像源 6.3.2.3 安装Docker 6.3.2.4 启动Docker并测试 6.3.3 Docker的中央仓库 6.3.4 Docker操作 6.3.4.1 镜像操作 6.3.4.…

从url获取参数并转为对象

const getParameters URL > JSON.parse({"${decodeURI(URL.split("?")[1]).replace(/"/g, \\").replace(/&/g, ",").replace(//g, ":")}"})getParameters("https://www.google.com.hk/search?qjsmd&neww…

【深度学习】李宏毅2021/2022春深度学习课程笔记 - Self-supervised Learning(自监督式学习)

文章目录一、芝麻街与进击的巨人二、Self-supervised Learning三、BERT3.1 Masking Input3.2 Next Sentence Prediction3.3 GLUE 任务集3.4 How to use BERT3.4.1 Case13.4.2 Case23.4.3 Case33.4.4 Case43.5 Training BERT is challenging!3.6 Pre-Training a Seq2Seq Model3.…

ERP是什么意思?

“ERP到底是一个怎么样的存在?为何有那么多的方面?如何学习?” 本文从ERP起源讲起,结合制造业离散制造与流程制造的ERP系统区别,详解ERP概念。 文章有点长,但如果你耐心看完,相信你会对ERP有一…

elasticsearch 基本语法(常见的RESTFUL API)

一 . ES的基本语法 文章目录一 . ES的基本语法1.Query String 语法2.Query DSL 语法3. Full-text queries 全文检索4. Phrase search 短语搜索5.Query and filter 查询和过滤6. Compound queries 查询7.HighLight search(高亮显示)测试数据内容:PUT /product/_doc/1…

科研试剂 Dextran-DBCO;葡聚糖-二苯并环辛烯;生物可降解高分子聚合物

DBCO修饰的葡聚糖聚 Dextran-DBCO 葡聚糖-二苯并环辛烯 名称:DBCO修饰葡聚糖 英文名称:Dextran-DBCO 外观状态:白色粉末 溶剂:DMSO等常规有机溶剂。 性状:基于不同的分子量,呈白色/类白色固体粉末&…

python爬虫(一)

一、理论 (1)URL管理器:网页之间的链接很复杂,a指向b,b指向a,如果不对其进行管理则可能导致重复爬取、循环爬取,因此单独用该模块进行管理。URL管理器有两个功能,分别是URL队列管理&…

神策营销云平台化应用实践

营销云是一个业务系统,需要贴合客户的实际业务场景,以平台化 分层设计撬动场景发挥价值主张。本文将详细介绍神策营销云在数字化转型浪潮中的沉淀。点击文末“阅读原文”立即观看完整版演讲回放。一、神策营销云产品理念“营销云是一个业务系统”&#…

规范有效的需求变更管理,分7步走。

1、建立需求基线 需要提前建立需求基线,需求基线是需求变更的依据,并需制定双方皆认可的需求变更流程。 需对用户需求进行明确分析,颗粒度越小越好。基准文件定位范围越详细,双方对需求越清晰,用户交流顺畅&#xff0c…

Go语言context包源码剖析

context包的作用 context包是在go1.7版本中引入到标准库中的 context可以用来在goroutine之间传递上下文信息,相同的context可以传递给运行在不同goroutine中的函数,上下文对于多个goroutine同时使用是安全的,context包定义了上下文类型&am…

两数之和【每日一题】

⭐前言⭐ ※※※大家好!我是同学〖森〗,一名计算机爱好者,今天让我们进入刷题模式。若有错误,请多多指教。更多有趣的代码请移步Gitee 👍 点赞 ⭐ 收藏 📝留言 都是我创作的最大的动力! 合抱之木…

MySQL数据库自动补全工具

MySQL数据库操作起来命令较多,默认无法使用tab键进行补全,所以可以安装一些实用的工具进行日常的操作 方式一:临时使用自动补全功能 mysql -u root -p --auto-rehash 方式二:永久使用自动补全功能 vi /etc/my.cnf [mysql] a…

Qt扫盲-QSqlDatabase理论总结

QSqlDatabase理论总结一、概述二、使用1. 连接数据库2. 数据库驱动3. 自定义数据驱动使用4. 注意事项三、常用的功能一、概述 QSqlDatabase类提供了通过连接访问数据库的接口。QSqlDatabase的一个实例表示一个数据库连接对象。该连接是通过Qt支持的数据库驱动程序来对数据库的…

再学C语言26:分支和跳转——goto语句

goto语句包括两个部分:goto和一个标签名称 goto point1; 为使goto语句工作,程序中必须包含由point1标签定位的其他语句 point1: printf("hello world! \n"); // 标签 冒号 一条语句 示例代码: /* test of goto */ #include &…

高一数学试题-2022年秋期末试卷

一、选择题 已知集合A{x∈N∣−2<x<52}A \{x \in \mathbf{N}| -2 < x < \frac{5}{2}\}A{x∈N∣−2<x<25​}&#xff0c;B{−2,−1,0,1,2,4}B \{-2, -1, 0, 1, 2, 4\}B{−2,−1,0,1,2,4}&#xff0c;则A∩BA \cap BA∩B A. {−1,0,1,2}\{-1, 0, 1, 2\}{−…

什么是AI预训练模型?

什么是预训练模型? 预训练 AI 模型是一种深度学习模型&#xff0c;在大型数据集上进行训练以完成特定任务&#xff0c;它可以按原样使用或定制以满足多个行业的应用需求。 想象一下&#xff0c;试图教一个蹒跚学步的孩子什么是独角兽。 一个好的起点可能是展示该生物的子图像…

[NOIP2017 提高组] 奶酪(C++,并查集)

题目背景 NOIP2017 提高组 D2T1 题目描述 现有一块大奶酪&#xff0c;它的高度为 hhh&#xff0c;它的长度和宽度我们可以认为是无限大的&#xff0c;奶酪中间有许多半径相同的球形空洞。我们可以在这块奶酪中建立空间坐标系&#xff0c;在坐标系中&#xff0c;奶酪的下表面…

用纯C实现单链表

前言 什么是单链表&#xff1f;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。链表的创建 需要创建一个小项目工程 创建三个文件 ⭐SListNode.h放单链表的头文件&#xff0c;函数声明 ⭐SListNode.c放单…