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

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

访客模式的优点:

  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. CDOJ 1060 秋实大哥与快餐店 字典树 水题

    题目链接 B - 秋实大哥与快餐店 Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%lld & %llu Sub ...

  2. 【BZOJ5249】IIIDX(贪心,线段树)

    题意: 思路:赛季结束之前余总推荐的一道好题,不愧是余总 From https://www.cnblogs.com/suika/p/8748115.html 简略的说就是在预留足够多的位置的前提下贪心 ...

  3. tf_upgrade_v2.exe实验

    实验前 import tensorflow as tf import numpy as np #create data x_data=np.random.rand(100).astype(np.flo ...

  4. 苹果cms开启防红跳转后,提示模板文件不存在解决方法

    1,苹果cms开启防红跳转后,提示模板文件不存在(如下图)这是因为你使用的模板里面缺少苹果cms自带的防红跳转模板导致,遇到这种状况后需要把苹果cms默认自带的( template/default_p ...

  5. 洛谷P2482 [SDOI2010]猪国杀——题解

    猪国杀,模拟题的一颗耀眼的明珠,成长大牛.锻炼码力必写题! 模拟题没什么思维难度.只要按部就班地去做就是.模拟简单在这,难也在这.因为题面巨长,条件巨多,忽疏一点都有可能全盘皆输.故推荐考试时碰见了, ...

  6. easyui 功能栏onclick传递object参数

    { field: 'Delete', title: '操作', width: 60, formatter: function (value, row, index) { var jrow = []; ...

  7. bootstrap editable初始化后表单可修改数据

    function loadData() { var url = "${ctx }/sys/marketing/product/page"; $('#tablepager').boo ...

  8. Phaser3 场景Scene之间的传值 -- HTML网页游戏开发

    一.首先当然得有至少有二个场景sceneA.js,sceneB.js 二.从场景A传值到场景B二种方法 1)通过事件this.events.emit('event key',{objKey:objVa ...

  9. 14 补充 MySQL的创建用户和授权

    权限管理 我们知道我们的最高权限管理者是root用户,它拥有着最高的权限操作.包括select.update.delete.update.grant等操作.那么一般情况在公司之后DBA工程师会创建一个 ...

  10. (转)WebRTC信令控制与STUN/TURN服务器搭建

    转:https://rtcdeveloper.com/t/topic/13742 本文将向大家介绍两个方面的知识: WebRTC信令控制 STUN/TURN服务器的搭建 在前面的文章中已经向大家介绍了 ...