C++设计模式:访客模式
访客模式:通俗的说, 就是定义一个访问者角色, 当对指定角色进行访问时要通过访问者进行访问。
访客模式的侵入性适中,仅在被访问的类里面加一个对外提供接待访问者的接口。
访客模式的优点:
- 符合单一职责原则. 具体元素角色负责数据的加载, 而访问者角色负责报表的展现, 两个不同的职责非常明确的分离开来, 各自演绎变化.
- 优秀的扩展. 由于职责分开,继续增加 对数据的操作是非常快捷的.
访客模式应用场景:
- 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
- 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
class Visitor;
//被访问类基类: 网站
class Website
{
public:
virtual ~Website(){ std::cout << "~Website()" << std::endl;}
virtual void accept(Visitor&) = 0;
};
//被访问类具体实现类: 淘宝网
class TaoBao : public Website
{
public:
void accept(Visitor &v) override;
void shopping();
};
//被访问类具体实现类: 优酷
class YouKu : public Website
{
public:
void accept(Visitor &v) override;
void playVideo();
};
//访客类基类
class Visitor
{
public:
Visitor() = default;
Visitor(const std::string &name) : m_name(name){}
virtual ~Visitor(){ std::cout << "~Visitor()" << std::endl;}
virtual void visit(TaoBao &web) = 0;
virtual void visit(YouKu &web) = 0;
protected:
std::string m_name{"unknow"};
};
//访客具体实现类: 普通游客用户
class GeneralVisitor : public Visitor
{
public:
void visit(TaoBao &web) override;
void visit(YouKu &web) override;
};
//访客具体实现类: VIP用户
class VIPVisitor : public Visitor
{
public:
VIPVisitor(const std::string &name) : Visitor(name){}
void visit(TaoBao &web) override;
void visit(YouKu &web) override;
};
//
void YouKu::accept(Visitor &v)
{
v.visit(*this);
}
void YouKu::playVideo()
{
std::cout << "Watch the video" << std::endl;
}
void TaoBao::accept(Visitor &v)
{
v.visit(*this);
}
void TaoBao::shopping()
{
std::cout << "Online shopping" << std::endl;
}
void GeneralVisitor::visit(TaoBao &web)
{
web.shopping();
}
void GeneralVisitor::visit(YouKu &web)
{
web.playVideo();
}
void VIPVisitor::visit(TaoBao &web)
{
std::cout << m_name << ": ";
web.shopping();
}
void VIPVisitor::visit(YouKu &web)
{
std::cout << m_name << ": ";
web.playVideo();
}
//测试
int main()
{
TaoBao tb;
YouKu yk;
GeneralVisitor gVisitor;
VIPVisitor vVisitor{"zhangsan"};
yk.accept(gVisitor);
tb.accept(gVisitor);
yk.accept(vVisitor);
tb.accept(vVisitor);
return 0;
}
从以上代码来看,当被访问类数量较多时,需要在访客类中对应的编写大量的方法。另外访客类中的方法实现依赖于被访客类的具体类,没有依赖于抽象类。
C++设计模式:访客模式的更多相关文章
- GoLang设计模式17 - 访客模式
说明 访客模式是一种行为型设计模式.通过访客模式可以为struct添加方法而不需要对其做任何调整. 来看一个例子,假如我们需要维护一个对如下形状执行操作的库: 方形(Square) 圆形(Circle ...
- 设计模式之visitor模式,人人能懂的有趣实例
设计模式,现在在网上随便搜都一大堆,为什么我还要写"设计模式"的章节呢? 两个原因: 1.本人觉得这是一个有趣的设计模式使用实例,所以记下来: 2.看着设计模式很牛逼,却不知道怎么 ...
- 每天一个设计模式-7 生成器模式(Builder)
每天一个设计模式-7 生成器模式(Builder) 一.实际问题 在讨论工厂方法模式的时候,提到了一个导出数据的应用框架,但是并没有涉及到导出数据的具体实现,这次通过生成器模式来简单实现导出成文本,X ...
- 每天一个设计模式-2 外观模式(Facade)
每天一个设计模式-2 外观模式(Facade) 1.生活中的示例 客户想要购买一台电脑,一般有两种方法: 1.自己DIY,客户需要知道组成电脑的所有电子器件,并且需要熟悉那些配件,对客户要求较高. ...
- 17. 星际争霸之php设计模式--职责链模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- 11. 星际争霸之php设计模式--备忘模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- 8. 星际争霸之php设计模式--享元模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- 7. 星际争霸之php设计模式--中介者模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- 6. 星际争霸之php设计模式--建造器模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
随机推荐
- (65)CRC32校验C语言版本
#include<iostream> # include <stdio.h> # include <string.h> typedef unsigned int u ...
- HDU1429--胜利大逃亡(续)(BFS+状态压缩)
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...
- 阿里知识储备之二——junit学习以及android单元测试
一,junit框架 http://blog.csdn.net/afeilxc/article/details/6218908 详细见这篇博客 juit目前已经可以和maven项目进行集成和测试,而且貌 ...
- sklearn 的 PolynomialFeatures 的用法
官方文档:http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PolynomialFeatures.html ...
- Oracle开发:dba和sysdba的区别
oracle dba和sysdba的区别如下: 1.dba是一种role对应的是对Oracle实例里对象的操作权限的集合,而sysdba是概念上的role是一种登录认证时的身份标识而已.而且,dba是 ...
- spring security跳过认证
在启动springboot的时候,给启动注解后添加这个exclude参数后接想要跳过的类就不会加载它了. @SpringBootApplication(exclude = { org.springfr ...
- LINK : fatal error LNK1104: 无法打开文件“qtmaind.lib”
LINK : fatal error LNK1104: 无法打开文件"qtmaind.lib" VS2019+QT5.13出现该问题,可以尝试这样解决. 1.找打qtmaind.l ...
- Centos 7 Redmine 安装,粘贴图片插件安装
转自: https://blog.csdn.net/jctian000/article/details/80591878 Redmine 是一个开源的.基于Web的项目管理和缺陷跟踪工具.它用日历和甘 ...
- 搜索练习题——FBI树
目录: ·题目描述 ·知识拓展 ·题目分析 ·思路分析 ·代码实现 ·总结 ·题目描述: (洛谷P1087 FBI树) 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称 ...
- web开发中会话跟踪的方法有哪些
会话跟踪就是浏览器和服务器通信 1.cookie 2.session 3.隐藏input 4.url重写 5.ip地址