当前位置: 首页 > news >正文

设计模式——访问者模式

访问者模式(Visitor)

   表示作用于某个对象结构中各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

在这里插入图片描述

代码举例

#include <iostream>
#include <string>
#include <list>
#include <memory>using namespace std;class Action;// 人的抽象类(Element)
class Person
{
public:virtual void Accept(shared_ptr<Action> visitor) = 0;
};// 注意forward declaration怎么写
class Man;
class Woman;// 状态的抽象类(Visitor)
class Action
{
public:virtual void GetManConclusion(const Man& concreteElementA) = 0;virtual void GetWomanConclusion(const Woman& concreteElementA) = 0;
};// 具体状态类
class Success : public Action
{
public:void GetManConclusion(const Man& concreteElementA) override{cout << "男人成功" << "时, 背后多半有一个伟大的女人。" << endl;}void GetWomanConclusion(const Woman& concreteElementB) override{cout << "女人成功" << "时, 背后大多有一个不成功的男人。" << endl;}
};class Failing : public Action
{
public:void GetManConclusion(const Man& concreteElementA) override{cout << "男人失败"  << "时, 蒙头喝酒,谁也不劝。" << endl;}void GetWomanConclusion(const Woman& concreteElementB) override{cout << "女人失败" <<  "时, 眼泪汪汪,谁也劝不了。" << endl;}
};class Amativeness : public Action
{
public:void GetManConclusion(const Man& concreteElementA) override{cout << "男人恋爱" << "时, 凡事不懂也要装懂。" << endl;}void GetWomanConclusion(const Woman& concreteElementB) override{cout << "女人恋爱" << "时, 遇事懂也装不懂。" << endl;}
};// 具体的Person, ConcreteElement
class Man : public Person
{
public:void Accept(shared_ptr<Action> visitor) override{visitor->GetManConclusion(*this);}
};class Woman : public Person
{
public:void Accept(shared_ptr<Action> visitor) override{visitor->GetWomanConclusion(*this);}
};// ObjectStructure类,提供一个高层的接口以允许枚举访问所有元素
class ObjectStructure
{
public:// 增加void Attach(shared_ptr<Person> element){elements_.push_back(element);}// 移除void Detach(shared_ptr<Person> element){elements_.remove(element);}// 打印void Display(shared_ptr<Action> visitor){for (auto& e : elements_){e->Accept(visitor);}}private:list<shared_ptr<Person>> elements_;
};// 客户端代码
void Client()
{ObjectStructure o;o.Attach(make_shared<Man>());o.Attach(make_shared<Woman>());// 成功的反应auto v1 = make_shared<Success>();o.Display(v1);// 失败的反应auto v2 = make_shared<Failing>();o.Display(v2);// 恋爱的反应auto v3 = make_shared<Amativeness>();o.Display(v3);
}int main()
{Client();return 0;
}

输出为

男人成功时, 背后多半有一个伟大的女人。
女人成功时, 背后大多有一个不成功的男人。
男人失败时, 蒙头喝酒,谁也不劝。
女人失败时, 眼泪汪汪,谁也劝不了。
男人恋爱时, 凡事不懂也要装懂。
女人恋爱时, 遇事懂也装不懂。

   由于使用了双分派,当我们需要添加一个新的状态的时候,只需要增加一个状态的子类,而不需要改动其他类的代码。

适用条件

   * 访问者模式适用于数据结构相对稳定的系统。例如上面的人分为男人和女人
   * 访问者模式将数据结构和作用于结构上的操作之间的耦合分开,使得操作可以相对自由的演化。
   * 增加新的操作实际上就是增加了数据结构的一个访问者。

   * 相应的,这个模式的缺点就是不方便增加新的数据结构。

相关文章:

  • python从入门到精通1:注释
  • Android 屏幕适配
  • python_根据关键词匹配文件中的数据并绘图
  • python学习—字典(Dictionary)
  • 【自动驾驶】运动底盘状态数据:里程计、IMU、运动学分析、串口通信协议
  • 计算机组成原理网课笔记2
  • 【刷力扣】23. 合并 K 个升序链表(dummy节点技巧 + 分治思维 + 优先队列)
  • 番外篇 | YOLOv8算法解析和实战应用:车辆检测 + 车辆追踪 + 行驶速度计算
  • 【shell脚本速成】函数
  • 五十三、openlayers官网示例Layer Spy解析——跟随鼠标透视望远镜效果、图层剪裁
  • LeetCode 3186 最大施法伤害
  • 如何选择适合的LabVIEW版本进行开发
  • 注解详解系列 - @ResponseStatus
  • Java中将文件转换为Base64编码的字节码
  • LabVIEW的热门应用
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • E-HPC支持多队列管理和自动伸缩
  • Java程序员幽默爆笑锦集
  • java中具有继承关系的类及其对象初始化顺序
  • Promise面试题,控制异步流程
  • 对超线程几个不同角度的解释
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 前嗅ForeSpider中数据浏览界面介绍
  • 让你的分享飞起来——极光推出社会化分享组件
  • 用mpvue开发微信小程序
  • 智能合约开发环境搭建及Hello World合约
  • - 转 Ext2.0 form使用实例
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • # Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型
  • #控制台大学课堂点名问题_课堂随机点名
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (1)Nginx简介和安装教程
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (WSI分类)WSI分类文献小综述 2024
  • (第30天)二叉树阶段总结
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • (转载)hibernate缓存
  • .NET CF命令行调试器MDbg入门(一)
  • .net core Redis 使用有序集合实现延迟队列
  • .net core 外观者设计模式 实现,多种支付选择
  • .NET delegate 委托 、 Event 事件
  • .NET MVC 验证码
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • .NET开发者必备的11款免费工具
  • .NET开源项目介绍及资源推荐:数据持久层