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

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

访客模式的优点:

  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. Logstash的filter插件介绍

    一 官网说明 过滤器插件对事件执行中介处理.通常根据事件的特征有条件地应用过滤器. 以下过滤器插件在下面可用. Plugin Description Github repository aggrega ...

  2. Spring Cloud云服务架构 - commonservice-eureka 项目构建过程

    我们针对于HongHu cloud的eureka项目做以下构建,整个构建的过程很简单,我会将每一步都构建过程记录下来,希望可以帮助到大家: 1. 创建一个名为particle-common-eurek ...

  3. 大v用户数据统计分析

    1,统计数据的基本情况,包括微博总数,用户总数,最活跃和最不活跃的用户id #!/bin/sh source_dir=/home/minelab/data/DATA source_file_name= ...

  4. springCloud分布式事务实战(一)案例需求及实现步骤

    本文不对分布式事务原理进行探索,而是通过一个案例来说明如何使用分布式事务 案例需求:创建2个基于springCloud的微服务,分别访问不同的数据库:然后创建一个整合服务,调用微服务实现数据的保存到2 ...

  5. Mybatis 自动生成mapper文件

    在pom.xml下的<build>内加入: <build> <plugins> <plugin> <groupId>org.mybatis. ...

  6. MySQL技术内幕 InnoDB存储引擎 之 InnoDB体系架构

    后台线程 1.Master Thread 2.IO Thread 3.Purge Thread 4.Page Cleaner Thread  内存 重做日志在以下三种情况下将重做日志缓存中的内容刷新到 ...

  7. 六、RF中断言关键字使用详解

    1.should be equal  和should be not equal  :比较两个值相等或不相等 2.should start with  和should not start with :判 ...

  8. Vue知识整理14:组件基础

    组件:可以复用的实例.使用 v-component来实现 2.通过props属性添加相应的属性,并且在模板中渲染 当模板中包含多个组件时,则需要用一个div来包裹起来.如下: 可以将原来的的点击事件, ...

  9. webpack打包文件解析

    /** * 对于没有代码分割的,webpack会打包生成main.js一个大的自执行函数 * 函数参数是一个对象,键值分别是路径和模块的函数 * 函数内部定义了一些方法,包括__webpack_req ...

  10. 查看dll中的函数(方法)

    https://jingyan.baidu.com/article/5553fa82b953b365a23934b7.html 查看dll中的函数(方法) 听语音 | 浏览:2004 | 更新:201 ...