C++ 设计模式之访问者模式
C++ 设计模式之访问者模式
简介
1、访问者模式 (Visitor)是一种行为型设计模式,它表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 使用该模式可以在不修改已有程序结构的前提下,通过添加额外的访问者类实现新的操作。
2、访问者模式 (Visitor)应用场景包括但不限于:
2.1、对象结构比较稳定,但操作经常变化的程序。
2.2、需要对一个对象结构中的对象进行很多不同而且不相关的操作,而你想避免让这些操作“污染”这些对象的类。
3、访问者模式 (Visitor)的构成
3.1、访问者(Visitor):定义了一个访问操作中的元素的接口。这个接口使得访问者可以不修改类的结构就可以增加新的操作。
class DocumentVisitor
{
public:virtual ~DocumentVisitor() {}virtual void visitParagraph(class ParagraphElement* element) = 0;virtual void visitImage(class ImageElement* element) = 0;virtual void visitTable(class TableElement* element) = 0;
};
3.2、元素(Element):声明一个接受访问者对象的接口。这个接口通常包含一个或多个由访问者接口定义的方法。
class DocumentElement
{
public:virtual ~DocumentElement() {}virtual void accept(DocumentVisitor* visitor) = 0;
};
4、访问者模式 (Visitor)的优点
4.1、封装性: 可以在不改变元素类的情况下定义新的操作。
4.2、扩展性: 新的访问者可以很容易地添加新的操作。
4.3、分离关注点: 移动相关的操作集中到访问者中,而不是分散在元素类中。
5、访问者模式 (Visitor)的缺点
5.1、违反封装: 访问者可能需要访问元素的内部细节,这通常意味着元素必须暴露一些原本应该是私有的数据。
5.2、复杂度: 可以使系统变得更加复杂,特别是当系统有大量元素时。
5.3、对象结构变化困难: 如果经常改变对象结构的元素类,那么维护访问者模式将会非常麻烦。
简单示例
1、定义
// 抽象访问者
class DocumentVisitor
{
public:virtual ~DocumentVisitor() {}virtual void visitParagraph(class ParagraphElement* element) = 0;virtual void visitImage(class ImageElement* element) = 0;virtual void visitTable(class TableElement* element) = 0;
};// 元素基类
class DocumentElement
{
public:virtual ~DocumentElement() {}virtual void accept(DocumentVisitor* visitor) = 0;
};class ParagraphElement : public DocumentElement
{
public:void accept(DocumentVisitor* visitor);
};class ImageElement : public DocumentElement
{
public:void accept(DocumentVisitor* visitor);
};class TableElement : public DocumentElement
{
public:void accept(DocumentVisitor* visitor);
};// 渲染访问者
class RenderVisitor : public DocumentVisitor
{
public:void visitParagraph(class ParagraphElement* element);void visitImage(class ImageElement* element);void visitTable(class TableElement* element);
};// 检查访问者
class CheckVisitor : public DocumentVisitor
{
public:void visitParagraph(class ParagraphElement* element);void visitImage(class ImageElement* element);void visitTable(class TableElement* element);
};
2、实现
void ParagraphElement::accept(DocumentVisitor* visitor)
{visitor->visitParagraph(this);
}void ImageElement::accept(DocumentVisitor* visitor)
{visitor->visitImage(this);
}void TableElement::accept(DocumentVisitor* visitor)
{visitor->visitTable(this);
}void RenderVisitor::visitParagraph(class ParagraphElement* element)
{std::cout << "Render Paragraph" << std::endl;
}void RenderVisitor::visitImage(class ImageElement* element)
{std::cout << "Render Image" << std::endl;
}void RenderVisitor::visitTable(class TableElement* element)
{std::cout << "Render Table" << std::endl;
}void CheckVisitor::visitParagraph(class ParagraphElement* element)
{std::cout << "Check Paragraph" << std::endl;
}void CheckVisitor::visitImage(class ImageElement* element)
{std::cout << "Check Image" << std::endl;
}void CheckVisitor::visitTable(class TableElement* element)
{std::cout << "Check Table" << std::endl;
}
3、调用
std::vector<DocumentElement*> vecDoc = {new ParagraphElement(),new ImageElement(),new TableElement()
};
RenderVisitor renderVisitor;
CheckVisitor checkVisitor;for (auto elem : vecDoc)
{elem->accept(&renderVisitor);elem->accept(&checkVisitor);
}for (auto el : vecDoc)
{delete el;
}
相关文章:
C++ 设计模式之访问者模式
C 设计模式之访问者模式 简介 1、访问者模式 (Visitor)是一种行为型设计模式,它表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 使用该模式可以在不修改已有程序结构的前提…...
linux——IPC 进程间通信
IPC 进程间通信 interprocess communicate IPC(Inter-Process Communication),即进程间通信,其产生的原因主要可以归纳为以下几点: 进程空间的独立性 资源隔离:在现代操作系统中,每个进程都…...
JAVA数字化产科管理平台源码:涵盖了孕妇从建档、产检、保健、随访、分娩到产后42天全流程的信息化管理
JAVA数字化产科管理平台源码:涵盖了孕妇从建档、产检、保健、随访、分娩到产后42天全流程的信息化管理 智慧产科管理系统是基于自主研发妇幼信息平台,为医院产科量身打造的信息管理系统,涵盖了孕妇从建档、产检、保健、随访、分娩到产后42天全…...
http数据传输确保完整性和保密性整流程方案(含源码)
往期文章回顾 【深度学习】 【深度学习】物体检测/分割/追踪/姿态估计/图像分类检测演示系统【含源码】【深度学习】YOLOV8数据标注及模型训练方法整体流程介绍及演示【深度学习】行人跌倒行为检测软件系统【深度学习】火灾检测软件系统【深度学习】吸烟行为检测软件系统【深度…...
UE插件与云渲染:10个提升效率的选择
Unreal Engine(虚幻引擎)的插件生态丰富多样,从提升视觉效果到优化工作流程,为开发者提供了无限扩展的可能。本文推荐10款备受欢迎的插件,助你激发创意,提升开发效率. 一、地牢建筑师:程序化关…...
[Shell编程学习路线]——shell脚本中case语句多分支选择详解
🏡作者主页:点击! 🛠️Shell编程专栏:点击! ⏰️创作时间:2024年6月21日16点30分 🀄️文章质量:95分 ————前言———— 在Shell编程中,处理多种条件…...
Django REST Framework(四)DRF Serializer
作用: 1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 2. 反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型 3. 反序列化,完成数据校验功能 定义序列化器 Django REST framework中的Serializer使用类来定义&a…...
【C语言】bool 关键字
在C语言中,bool类型用于表示布尔值,即真或假。C语言本身在标准库中并未提供布尔类型,直到C99标准引入了stdbool.h头文件。该头文件定义了bool类型,以及两个常量:true和false。在此之前,通常使用整数来表示布…...
开发电商ERP系统需要接入哪些平台API?
跟随全渠道发展趋势,很多实体商家开设电商店铺,为消费者提供便捷的购物体验,增强消费者的满意度,同时也提升了企业自身的市场竞争力。为了满足商家业务拓展需求,很多原本主要服务于实体商贸企业的ERP服务商,…...
Meet AI4S 直播预告丨房价分析新思路:神经网络直击复杂地理环境中的空间异质性
近年来,房地产市场起起落落,房价已经成为了扰动居民幸福感的重要影响因素。大多数家庭都需要面对「买不买房、何时买房、在哪儿买房、买什么房」的艰难抉择,每一个问题的答案都在某种程度上与房价的波动息息相关。 近年来,我国各…...
支持向量机(SVM)在机器学习中的简单示例
目录 工作原理 核函数 SVM用于分类 结果分析 结论 ❤❤❤动动发财的小手点点赞点点关注哦~~~❤❤❤ 支持向量机是一种强大的监督学习模型,用于分类和回归任务。它通过找到数据点之间的最优边界来区分不同的类别。SVM特别适用于那些具有清晰边界但线性不可分的…...
使用Anaconda虚拟环境安装Opencv、pytorch、torchvision踩坑记录
电脑 python 环境版本过高与下载Opencv(3.4以下)不匹配,因为版本过高部分算法收米, 从而在虚拟环境重新下载python老版本 本文默认您的电脑上已经安装了Anaconda 我是按照这位博文安装的 安装Opencv (详解)安装3.4.1.15版本…...
【人工智能】CPU、GPU与TPU:人工智能领域的核心处理器概述
在人工智能和计算技术的快速发展中,CPU(中央处理器)、GPU(图形处理器)和TPU(张量处理器)作为核心处理器,各自扮演着不可或缺的角色。它们不仅在性能上各有千秋,还在不同的…...
【康复学习--LeetCode每日一题】3099. 哈沙德数
题目: 如果一个整数能够被其各个数位上的数字之和整除,则称之为 哈沙德数(Harshad number)。给你一个整数 x 。如果 x 是 哈沙德数 ,则返回 x 各个数位上的数字之和,否则,返回 -1 。 示例 1&a…...
docker使用jdk21启动jar包报错
[0.007s][warning][os,thread] Failed to start thread "GC Thread#0" - pthread_create failed (EPERM) for attributes: stacksize: 1024k, guardsize: 4k, detached. [0.007s][error ][gc,task ] Failed to create worker thread解决办法 1 (使用doc…...
Object 类中的公共方法详解
Object 类中的公共方法详解 1、clone() 方法2、equals(Object obj) 方法3、hashCode() 方法4、getClass() 方法5、wait() 方法6、notify() 和 notifyAll() 方法 💖The Begin💖点点关注,收藏不迷路💖 在 Java 中,Object…...
python 字典 一个key 多 value 遍历
在Python中,如果一个键对应多个值,你需要确保这些值被存储在一个容器类型(如列表或集合)中。你可以使用默认字典(collections.defaultdict)来简化这个过程。以下是一个示例代码: from collecti…...
vue---基本原理(二)
1、slot的基础理解 slot又名插槽,是vue的内容分发机制,组件内部的模板引擎使用slot元素作为承载分发的出口。是子组件的一个模板标签元素,而这一个标签元素是否显示,以及怎么显示,是由父元素控制的。slot又分为默认插槽…...
桂花网蓝牙网关X1000:引领物联网新时代的智能连接
在物联网技术飞速发展的今天,蓝牙网关作为连接蓝牙设备与互联网的关键设备,其性能与稳定性直接影响到物联网系统的整体运行效果。桂花网蓝牙网关X1000凭借其卓越的性能和广泛的应用场景,成为了物联网领域的佼佼者。 一、产品概述 桂花网蓝牙…...
JAVA案例模拟电影信息系统
一案例要求: 二具体代码(需要在同一个包下创建三个类) Ⅰ:实现类 package 重修;import java.util.Random; import java.util.Scanner;public class first {public static void main(String[] args) {javabean[]moviesnew javabean[4];movies[0] new ja…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
