访客模式:通俗的说, 就是定义一个访问者角色, 当对指定角色进行访问时要通过访问者进行访问。

访客模式的侵入性适中,仅在被访问的类里面加一个对外提供接待访问者的接口。

访客模式的优点:

  1. 符合单一职责原则. 具体元素角色负责数据的加载, 而访问者角色负责报表的展现, 两个不同的职责非常明确的分离开来, 各自演绎变化.
  2. 优秀的扩展. 由于职责分开,继续增加 对数据的操作是非常快捷的.

访客模式应用场景:

  1. 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
  2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
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++设计模式:访客模式的更多相关文章

  1. GoLang设计模式17 - 访客模式

    说明 访客模式是一种行为型设计模式.通过访客模式可以为struct添加方法而不需要对其做任何调整. 来看一个例子,假如我们需要维护一个对如下形状执行操作的库: 方形(Square) 圆形(Circle ...

  2. 设计模式之visitor模式,人人能懂的有趣实例

    设计模式,现在在网上随便搜都一大堆,为什么我还要写"设计模式"的章节呢? 两个原因: 1.本人觉得这是一个有趣的设计模式使用实例,所以记下来: 2.看着设计模式很牛逼,却不知道怎么 ...

  3. 每天一个设计模式-7 生成器模式(Builder)

    每天一个设计模式-7 生成器模式(Builder) 一.实际问题 在讨论工厂方法模式的时候,提到了一个导出数据的应用框架,但是并没有涉及到导出数据的具体实现,这次通过生成器模式来简单实现导出成文本,X ...

  4. 每天一个设计模式-2 外观模式(Facade)

    每天一个设计模式-2  外观模式(Facade) 1.生活中的示例 客户想要购买一台电脑,一般有两种方法: 1.自己DIY,客户需要知道组成电脑的所有电子器件,并且需要熟悉那些配件,对客户要求较高. ...

  5. 17. 星际争霸之php设计模式--职责链模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  6. 11. 星际争霸之php设计模式--备忘模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  7. 8. 星际争霸之php设计模式--享元模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  8. 7. 星际争霸之php设计模式--中介者模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  9. 6. 星际争霸之php设计模式--建造器模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

随机推荐

  1. [BZOJ1059]:[ZJOI2007]矩阵游戏(二分图匹配)

    题目传送门 题目描述 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N×N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种 ...

  2. &&的运算顺序

    先判断“&&”左侧的表达式,左侧的表达式为真时,再运算右侧的表达式.如左侧为假,则不运算右侧.

  3. 不能访问windows installer服务

    xp系统安装msi类型的安装程序出现以下错误: 不能访问windows installer服务. 解决办法 1:运行cmd -> regsvr32 msi.dll 运行services.msc- ...

  4. tensorflow学习——调试ctc的两个bug

    InvalidArgumentError (see above for traceback): Not enough time for target transition sequence (requ ...

  5. python3 导入模块

    python3导入模块和python2  有些不同   需要指定相对目录 如,在Project下有一个nlp目录里面有一个ltp模块,则 from n1.ltp import Clawer

  6. gvim安装中文文档

    今天下载了个gvim一直无法安装中文中文文档,以为是版本原因,又下了几个版本,后来发现都不行. 最后发现是文档安装位置不对,需要放到vim/vim47目录下才行 以下是翻墙在官网下的gvim74和vi ...

  7. WAMP搭建与配置

    使用WampServer整合软件包进行WAMP环境搭建 WampServer是一款由法国人开发的Apache Web服务器.PHP解释器以及MySQL数据库的整合软件包.免去了开发人员将时间花费在繁琐 ...

  8. 如何进行EDM邮件内容的撰写

    近两个月没有来博客园更新一下博客文章了,实在惭愧,最近忙于工作,经常加班.下面来说说EDM邮件内容的撰写技巧吧,本文就跟大家交流一下自己一直以来的心得体会. EDM中很重要的一个步骤,就是邮件内容的撰 ...

  9. Python中的Django框架中prefetch_related()函数对数据库查询的优化

    实例的背景说明 假定一个个人信息系统,需要记录系统中各个人的故乡.居住地.以及到过的城市.数据库设计如下: Models.py 内容如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 1 ...

  10. IntelliJ IDEA调试时,格式化显示日期变量

    格式化前: 格式化后: new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this); 入门常用知识: Ct ...