设计模式C++描述----22.访问者(Visitor)模式
一. 访问者模式
定义:表示一个作用于某对象结构中的各元素的操作。它你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
结构如下:

二. 举例
假设有一项科学实验,是用来对比两种种子在不同环境下的生长情况。
两种种子,一种是普通的种子(Seed_A),一种是太空运回的种子(Seed_B)。
生长环境,分别是在多雨环境下(Rain_Status),阳光环境下(Sun_Status)等等。
结构如下:

代码如下:
- //状态
- class Status
- {
- public:
- virtual ~Status() {}
- virtual void VisitSeed_A(Seed* elm) {}
- virtual void VisitSeed_B(Seed* elm) {}
- protected:
- Status() {}
- };
- //下雨状态
- class Rain_Status:public Status
- {
- public:
- Rain_Status() {}
- virtual ~Rain_Status() {}
- //下雨状态下A种子生长的情况
- virtual void VisitSeed_A(Seed* elm)
- {
- cout<<"Rain will visit Seed A..."<<endl;
- }
- //下雨状态下B种子生长的情况
- virtual void VisitSeed_B(Seed* elm)
- {
- cout<<"Rain will visit Seed B..."<<endl;
- }
- };
- //阳光状态
- class Sun_Status:public Status
- {
- public:
- Sun_Status() {}
- virtual ~Sun_Status() {}
- //阳光状态下A种子生长的情况
- virtual void VisitSeed_A(Seed* elm)
- {
- cout<<"Sun will visit Seed A..."<<endl;
- }
- //阳光状态下B种子生长的情况
- virtual void VisitSeed_B(Seed* elm)
- {
- cout<<"Sun will visit Seed B..."<<endl;
- }
- };
- //种子
- class Seed
- {
- public:
- virtual ~Seed() {}
- virtual void Accept(Status* vis) = 0;
- protected:
- Seed() {}
- };
- //种子A,假设为普通种子
- class Seed_A:public Seed
- {
- public:
- Seed_A() {}
- ~Seed_A() {}
- void Accept(Status* vis)
- {
- vis->VisitSeed_A(this);
- }
- };
- //种子B,假设为从太空带回来的种子
- class Seed_B:public Seed
- {
- public:
- Seed_B() {}
- ~Seed_B() {}
- void Accept(Status* vis)
- {
- vis->VisitSeed_B(this);
- }
- };
- //对象结构类,为了对比不同种子
- class ObjectStructure
- {
- private:
- list<Seed*> lseed;
- public:
- //Add
- void Attach(Seed* seed)
- {
- lseed.push_back(seed);
- }
- //Delete
- void Detach(Seed* seed)
- {
- lseed.remove(seed);
- }
- //Show
- void Display(Status* status)
- {
- list<Seed*>::iterator it = lseed.begin();
- for (it; it != lseed.end(); ++it)
- {
- (*it)->Accept(status);
- }
- }
- };
- //测试代码
- int main(int argc,char* argv[])
- {
- ObjectStructure obj;
- //加入要对比的两个种子
- obj.Attach(new Seed_A());
- obj.Attach(new Seed_B());
- //查看各种状态下两个种子的情况
- obj.Display(new Rain_Status());
- //Sun Satte
- obj.Display(new Sun_Status());
- return 0;
- }
三. 说明
1. 首先有一点要明确,就是两种种子不会轻易改变,也就是只有普通和太空种子两种。换句话说就是,数据结构比较稳定。
2. 可以变的是新增的状态,比如增加一个X光下的生成情况,等等。说白了就是,操作集合可以相对自由的演化。
3. 这种结构的优点是,增加新的操作很容易;缺点是,增加新的数据结构有点困难,因为你要在每一个访问者里都添加相应的操作。
4. 种子生长图相对于访问者模式的结构图有如下关系:
seed(种子)相当于 element(元素),这个是不怎么变的。
status(状态) 相当于 visitor(访问者),这个是可变且易变的。要注意的是,每个访问者都要对所有的元素(element)进行操作。
5. 事实上我们很少用这种模式,因为数据结构(element)不变的情况很少。
设计模式C++描述----22.访问者(Visitor)模式的更多相关文章
- 设计模式之第22章-组合模式(Java实现)
设计模式之第22章-组合模式(Java实现) “鱼哥,有没有什么模式是用来处理树形的“部分与整体”的层次结构的啊.”“当然”“没有?”“有啊.别急,一会人就到了.” 组合模式之自我介绍 “请问你是?怎 ...
- 《图解设计模式》读书笔记6-1 VISITOR模式
目录 1. Visitor模式简介 2. 示例 2.1 类图 2.2 代码 3. 模式的角色和类图 4. 思路拓展 4.1 双重分发 4.2 开闭原则 4.3 难以增加ConcreteElement角 ...
- 设计模式-访问者(Visitor)模式
访问者模式是对象的行为模式.访问者模式的目的是封装施加在某种数据结构元素上的操作.一旦一些操作需要修改,接受这个操作的数据结构可以保持不变. 个人觉得访问者模式相对其他的设计模式来说稍微复杂,难理解一 ...
- [设计模式]访问者 Visitor 模式
访问者模式是对象的行为模式. 访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变.
- C++设计模式实现--訪问者(Visitor)模式
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/L_Andy/article/details/36896645 一. 訪问者模式 定义:表示一个作用于 ...
- 设计模式C++描述----09.桥接(Bridge)模式
一. 举例 N年前: 计算机最先出来时,软件和硬件是一绑在一起的,比如IBM出了一台电脑,上面有一个定制的系统,假如叫 IBM_Win,这个IBM_Win系统当然不能在HP电脑上运行,同样HP出的HP ...
- 设计模式C++描述----21.解释器(Iterpreter)模式
一. 解释器模式 定义:给定一个语言,定义它的文法的一种表示,并定一个解释器,这个解释器使用该表示来解释语言中的句子. 结构如下: 代码如下: //包含解释器之外的一些全局信息 class Conte ...
- 设计模式C++描述----20.迭代器(Iterator)模式
一. 举例说明 我们知道,在 STL 里提供 Iterator 来遍历 Vector 或者 List 数据结构. Iterator 模式也正是用来解决对一个聚合对象的遍历问题,将对聚合的遍历封装到一个 ...
- 设计模式C++描述----19.命令(Command)模式
一. 举例说明 我们知道,在多线程程序中,多个用户都给系统发 Read 和 Write 命令.这里有几点需要说明: 1. 首先明确一点,所有的这些 Read 和 Write 命令都是调用一个库函数. ...
随机推荐
- mybatis #{}和${}的区别是什么?
#{}是预编译处理,${}是字符串替换.mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值,最后注入进去是带引号的:mybatis在 ...
- 性能优化:虚拟列表,如何渲染10万条数据的dom,页面同时不卡顿
列表大概有2万条数据,又不让做成分页,如果页面直接渲染2万条数据,在一些低配电脑上可能会照成页面卡死,基于这个需求,我们来手写一个虚拟列表 思路 列表中固定只显示少量的数据,比如60条 在列表滚动的时 ...
- Spring boot 官网学习笔记 - Spring DevTools 介绍
想要使用devtools支持,只需使用dependencies将模块依赖关系添加到你的构建中 运行打包的应用程序时,开发人员工具会自动禁用.如果你通过 java -jar或者其他特殊的类加载器进行启动 ...
- 如何把安全证书导入到java中的cacerts证书库
每一步:进入某个https://www.xxx.com开头的网站,把要导入的证书下载, 在该网页上右键 >> 属性 >> 点击"证书" >> 再 ...
- 2.html5新布局元素
1.html5的优点: ①对人友好,更加语义化,更直观,增加了代码的可读性. ②对计算机友好,浏览器更容易解析,搜索引擎更容易抓取文档内容. ③代码更加的简洁. 2.新增的布局标签: Article: ...
- 阿里云服务器CentOS6.9安装Tomcat
上篇讲了CentOS6.9安装jdk,这篇来讲Tomcat的安装,本来准备使用yum命令安装的,但是通过 yum search tomcat 发现只有tomcat6,所以就在官网下了一个tomcat8 ...
- mysql初识笔记
一.初始mysql mysql介绍: mysql版本: 版本号=3个数字+1个后缀 mysql-5.0.9-beta 5 0 9 Beta 主版本号 发行级别 发行稳定级别 发行系列 发行系列的版本号 ...
- 说说 Java 线程间通信
序言 正文 一.Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在一个 ...
- Kubernetes 系列(三):Kubernetes使用Traefik Ingress暴露服务
一.Kubernetes 服务暴露介绍 从 kubernetes 1.2 版本开始,kubernetes提供了 Ingress 对象来实现对外暴露服务:到目前为止 kubernetes 总共有三种暴露 ...
- Docker系列(五):.Net Core实现k8s健康探测机制
k8s通过liveness来探测微服务的存活性,判断什么时候该重启容器实现自愈.比如访问 Web 服务器时显示 500 内部错误,可能是系统超载,也可能是资源死锁,此时 httpd 进程并没有异常退出 ...