设计模式之访问者

news2024/12/27 11:29:14

一、访问者设计模式概念

        访问者模式(Visitor) 是一种行为设计模式, 它能将算法与其所作用的对象隔离开来。

 适用场景

  • 如果你需要对一个复杂对象结构 (例如对象树) 中的所有元素执行某些操作, 可使用访问者模式。
  • 可使用访问者模式来清理辅助行为的业务逻辑。
  • 当某个行为仅在类层次结构中的一些类中有意义, 而在其他类中没有意义时, 可使用该模式。

访问者设计模式的结构

  1. 访问者 (Visitor) 接口声明了一系列以对象结构的具体元素为参数的访问者方法。 如果编程语言支持重载, 这些方法的名称可以是相同的, 但是其参数一定是不同的。
  2. 具体访问者 (Concrete Visitor) 会为不同的具体元素类实现相同行为的几个不同版本。
  3. 元素 (Element) 接口声明了一个方法来 “接收” 访问者。 该方法必须有一个参数被声明为访问者接口类型。
  4. 具体元素 (Concrete Element) 必须实现接收方法。 该方法的目的是根据当前元素类将其调用重定向到相应访问者的方法。 请注意, 即使元素基类实现了该方法, 所有子类都必须对其进行重写并调用访问者对象中的合适方法。
  5. 客户端 (Client) 通常会作为集合或其他复杂对象 (例如一个组合 (opens new window)树) 的代表。 客户端通常不知晓所有的具体元素类, 因为它们会通过抽象接口与集合中的对象进行交互。

代码如下:

        问题:做一款生成冰激凌和雪糕的程序,要求可以扩展新的口味,并且可以扩展新的包装方式。
        解决方案:表示一个作用于某对象结构中的各元素的操作。
    它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

#include <iostream>
#include <string>
#include <vector>
class IceCream;
class Popsicle;
class Visitor
{
public:
	virtual void visitIceCream(const IceCream *iceCream)const = 0;
	virtual void visitPopsicle(const Popsicle *popsicle)const = 0;
};

class Component
{
public:
    	virtual void accept(Visitor* visitor) const = 0;
};

class IceCream : public Component
{
public:
	virtual void accept(Visitor* visitor) const
	{
		visitor->visitIceCream(this);
	}
	std::string getIceCream()const
	{
		return "冰激凌";
	}
};

class Popsicle : public Component
{
public:
	virtual void accept(Visitor* visitor) const
	{
		visitor->visitPopsicle(this);
	}
	std::string getPopsicle()const
	{
		return "雪糕";
	}
};

class Frosting : public Visitor
{
public:
	void visitIceCream(const IceCream* iceCream)const override
	{
		std::cout << iceCream->getIceCream() << " + 糖霜" << std::endl;

	}
	void visitPopsicle(const Popsicle* popsicle)const override
	{
		std::cout << popsicle->getPopsicle() << " + 糖霜" << std::endl;
	}
};

class Chocolate : public Visitor
{
public:
	void visitIceCream(const IceCream* iceCream)const override
	{
		std::cout << iceCream->getIceCream() << " + 巧克力" << std::endl;

	}
	void visitPopsicle(const Popsicle* popsicle)const override
	{
		std::cout << popsicle->getPopsicle() << " + 巧克力" << std::endl;
	}
};

void clientCode(const std::vector<Component*>& components,Visitor* visitor)
{
	for (const auto& component : components)
	{
		component->accept(visitor);
	}
}

int main()
{
	std::vector<Component*> components = { new IceCream,new Popsicle,new Popsicle };
	Frosting frosting;
	clientCode(components, &frosting);
	Chocolate chocolate;
	clientCode(components, &chocolate);
	return 0;
}

 二、与其他模式的关系

  • 你可以将访问者模式 (opens new window)视为命令模式 (opens new window)的加强版本, 其对象可对不同类的多种对象执行操作。
  • 你可以使用访问者 (opens new window)对整个组合模式 (opens new window)树执行操作。
  • 可以同时使用访问者 (opens new window)和迭代器模式 (opens new window)来遍历复杂数据结构, 并对其中的元素执行所需操作, 即使这些元素所属的类完全不同。

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

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

相关文章

King3399 SDK(ubuntu文件系统)编译简明教程

该文章仅供参考&#xff0c;编写人不对任务实验设备、人员及测量结果负责&#xff01;&#xff01;&#xff01; 0 引言 文章主要介绍King3399&#xff08;瑞芯微rk3399开发板&#xff0c;荣品&#xff09;官方SDK&#xff08;Ubuntu文件系统&#xff09;编译过程&#xff0c…

Linux bash脚本 远程开发环境配置

参考资料 太香了&#xff0c;VSCode远程开发插件&#xff0c;值得一试Visual Studio Code で Remote SSH する。Managing extensions 目录 一. 远程开发必备二. 连接远程开发服务器三. 安装远程开发插件 一. 远程开发必备 ⏹ VSCode插件 Remote - SSH 通过使用 SSH 链接虚拟…

司法质量改善:巡回法庭的准自然实验(2000-2022年)(原始数据、计算代码、最终计算结果(Excel和Dta)和参考文献)

巡回法庭的设立背景 最高人民法院自2015年起分批次设立地方巡回法庭&#xff0c;以期改善司法质量&#xff0c;促进司法公正。这种改革措施为研究提供了一个独特的机会&#xff0c;可以通过准自然实验的方法来评估其效果。 2000-2022年司法质量改善&#xff1a;巡回法庭的准自…

PYTHON实现HTTP request的一些有用的函数

前言 我们知道&#xff0c;当需要设计一个程序和服务器进行交互时&#xff0c;往往会用到HTTP的request&#xff0c;即服务器有一个对外接口REST API&#xff0c;因此当向服务器发送符合格式要求的HTTP request时&#xff0c;服务器会给出响应&#xff0c;甚至执行一些任务。如…

机器学习模型算法

前言 机器学习离不开数据、和模型算法&#xff0c;常用的套路包含数据预处理、模型学习、模型评估、样本预测几个步骤。 数据预处理&#xff1a;从原始raw数据&#xff0c;经过&#xff08;特征处理幅度缩放、特征选择、维度约减、采样&#xff09;&#xff0c;输出测试集和训…

Java 16Java 17(LTS版本)新特性概述

一、Java 16 发布于2021年3月16日。Java 16主要特性有&#xff1a; JEP 338&#xff1a;Vector API (Incubator) 向量 API&#xff08;第一轮孵化&#xff09; JEP 387&#xff1a;Elastic Metaspace 弹性元空间 JEP 389&#xff1a;Foreign Linker API (Incubator) 外部链接…

鸿蒙OpenHarmony

开源鸿蒙系统编译指南 Ubuntu编译环境配置第一步&#xff1a;Shell 改 Bash第二步&#xff1a;安装Git和安装pip3工具第三步&#xff1a;远程仓配置第四步&#xff1a;拉取代码第五步&#xff1a;安装编译环境第六步&#xff1a;本地编译源码 Windows开发环境配置第一步&#x…

生信初学者教程(二十四):筛选交集特征

文章目录 介绍加载R包导入数据重叠的重要特征重要特征的韦恩图输出结果总结介绍 在数据分析和机器学习项目中,特征选择是一个至关重要的步骤,它有助于识别数据集中与目标变量最相关的特征。当通过不同的机器学习方法筛选出重要特征时,对这些特征取交集以识别核心特征,是一种…

【重学 MySQL】五十、添加数据

【重学 MySQL】五十、添加数据 使用INSERT INTO语句添加数据基本语法示例插入多行数据注意事项 使用LOAD DATA INFILE语句批量添加数据其他插入数据的方式注意事项 在MySQL中&#xff0c;添加数据是数据库操作中的基本操作之一。 使用INSERT INTO语句添加数据 使用 INSERT IN…

资源《Arduino UNO R3 proteus 仿真工程》说明。

资源链接&#xff1a; Arduino UNO R3 proteus 仿真工程 1.文件明细&#xff1a; 2.文件内容说明 包含&#xff1a;AD工程、原理图、PCB。 3.内容展示 4.简述 该文件为proteus工程&#xff0c;用于Arduino uno r3仿真。 因为软件自动运行&#xff0c;所以最小系统上没有…

全网最适合入门的面向对象编程教程:55 Python字符串与序列化-字节序列类型和可变字节字符串

全网最适合入门的面向对象编程教程&#xff1a;55 Python 字符串与序列化-字节序列类型和可变字节字符串 摘要&#xff1a; 在 Python 中&#xff0c;字符编码是将字符映射为字节的过程&#xff0c;而字节序列&#xff08;bytes&#xff09;则是存储这些字节的实际数据结构&am…

论文笔记:iCaRL: Incremental Classifier and Representation Learning

1. Contribution 提出了一种新的训练策略&#xff0c;iCaRL&#xff1a;允许以增量方式学习&#xff1a;只需要同时存在一小部分类别的训练数据&#xff0c;新类别可以逐步添加。同时学习分类器和数据表示&#xff1a;iCaRL能够同时学习强大的分类器和数据表示&#xff0c;这与…

OpenGL ES MVP/变换投影矩阵(8)

OpenGL ES MVP/变换投影矩阵(8) 简述 通过前面几节的学习&#xff0c;目前我们已经可以渲染自己想要的图像&#xff0c;也可以通过纹理加载图片进行渲染。接下来我们来学习一下MVP&#xff0c;这里的MVP不是Android应用开发里的框架MVP&#xff0c;而是Model&#xff0c;View…

电场能量磁场能量相等,注意电场能量公式也没有复数形式(和坡印廷类似)

下面是电场能量密度和磁场能量密度的公式&#xff0c;注意这可不是坡印廷定理。且电场能量密度没有复数表达式&#xff0c;即不是把E和D换成复数形式就行的。注意&#xff0c;一个矢量可以转化为复数形式&#xff0c;两个矢量做运算不能转化为两个复数形式的矢量做运算&#xf…

什么是SPI机制

什么是SPI机制 SPI机制是Java平台提供的一种强大的动态扩展机制&#xff0c;能够让程序在运行时灵活地加载和使用服务提供者的实现类。我们这里带大家简单的了解一下SPI机制是如何工作的 SPI&#xff08;Service Provider Interface&#xff0c;服务提供者接口&#xff09;机制…

JavaScript while循环语句

While语句包括一个循环条件和一段代码块&#xff0c;只要条件为真&#xff0c;就不断循环执行代码块。 while(条件){语句;} var i0;while(i<100){console.log(i);i1;} 注意&#xff1a;所有的for循环都可以改写为while循环

Spring Boot 和 MyBatis-Plus凑一块儿了,这份教程你得看

一、引言 MyBatis-Plus 是 MyBatis 的增强版&#xff0c;提供了 CRUD 接口、分页插件、性能分析插件等特性&#xff0c;简化了开发过程。本文将详细介绍如何在 Spring Boot 项目中集成 MyBatis-Plus。 支持的数据看也越来越多&#xff0c;值得去搞一下&#xff0c;写了一个小例…

《PMI-PBA认证与商业分析实战精析》第5章 需求启发与分析

第5章 需求启发与分析 本章主要内容&#xff1a; 需求启发 需求分析 模型化与优化需求 记录、确认、核实和批准需求 本章涵盖的考试重点&#xff1a; 需求启发的四项活动 需求启发的八项技术 启发提问的四种类型问题 启发原型的类型 访谈的四种分类 观察技术的四种类…

华三资源

华三华三官方网站华三公司官网新华三 - 融绘数字未来&#xff0c;共享美好生活华三华三文档中心华三文档资源文档中心-新华三集团-H3C华三华三 ICT百科华三 ICT知识百科H3C ICT知识百科-新华三集团-H3C华三华三文档高级查找高级文档搜索新华三 - 融绘数字未来&#xff0c;共享美…

已解决:Could not find artifact xxx

已解决&#xff1a;Could not find artifact xxx 文章目录 写在前面问题描述报错原因分析 解决思路解决办法1. 检查依赖声明的正确性2. 检查远程仓库配置3. 检查网络连接4. 清理本地缓存并强制更新5. 手动上传依赖到私有仓库6. 检查本地仓库是否已被损坏 总结 写在前面 在使用…