visitor模式最基本的是访问者和被访问者。它的优势是不用改变被访问类的任何结构就可以对被访问者施加新的操作,前提是增加一个访问者的子类。其实就是用增加访问者子类的方法替代被访问者方法的增加。

用你不需要的便利换取你需要的功能。

访问者执行一些对被访问者的一些操作,实现方式是在被访问者中调用访问者的方法,把自己(this指针)传进去。这样对被访问者的一次调用被隐式转移到访问者对被访问者的一些处理。但这样有问题,被访问者要知道访问者基类,访问者要知道所有的被访问者子类。

Acyclic Visitor做的事情是:

Visitor基类只是一个基类(稻草人),它对一切都无所知。但是被访问者要知道Visitor的继承者,也就是真是的访问者,被访问者依据dynamic_cast得到具体的visitor,然后调用visitor的定制方法。这个变种模式使得visitor不需要知道任何visited,只有visited单向的需要知道visitor。

但是,特定的visited的访问者需要知道这个特定的visited。所以这个问题的解决方案可以用代码简单描述为:

// f1    visitor base file
class  Visitor
... {
    virtual    void    ~Visitor();
} ;

// f2    visitor-A file
class  A;
class  VisitorA    : public  Visitor
... {
public:
    void    DoVisitA(A& a)...{}
} ;

// f3    visitor-B file
class  B;
class  VisitorB    : public  Visitor
... {
public:
    void    DoVisitB(B& b)...{}
} ;

// f4    class A file
class  VisitorA;
class  A    : public  Base
... {
public:
    void    Accept(Visitor& v)
    ...{
        if (VisitorA& va = dynamic_cast<VisitorA>(v))
        ...{
            va.DoVisitA(*this);
        }
        else
        ...{
            //default visit operator
        }
    }
} ;

// f5    class B file
class  VisitorB;
class  B : public  Base
... {
public:
    void    Accept(Visitor& v)
    ...{
        if (VisitorB& vb = dynamic_cast<VisitorB>(v))
        ...{
            vb.DoVisitB(*this);
        }
        else
        ...{
            //default visit operator
        }
    }
} ;

// f6    concret visitor
// #include class A,class B
class  ConcretVisitor
    : public     VisitorA, public  VisitorB
... {
public:
    void    VisitorA();    //do process self data
    void    VisitorB();    //do process self data
} ;

// while use
ConcretVisitor    mv;
A                ma;
B                mb;
ma.Accept(mv);
mb.Accept(mv);
mv. out - put - self - data;

fn代表第n个文件,可以看到,特定的visitor只需知道与自己对于的visited就可以了。而visited某种程度上也是这样。只不过,ConcretVisitor需要知道一切,这是肯定的,因为它是终端用户。这个方案很好解决了循环引用的问题,所以这叫Acyclic(非循环的)。

请注意一个名词:名称上的依存。这意味着,虽然是依存,但这仅仅需要前置声明就可以,不必须包含文件。

Visitor模式与Acyclic Visitor相关推荐

  1. 再议访问者模式 - Visitor vs Acyclic Visitor

    访问者模式的应用条件相对苛刻一些.通常它被使用在类似于这种场景:被访问类不太会增加新的子类,但是它的方法会经常变动. 先来简单回顾一些经典访问者. 传统Visitor模式 假设我们需要创建一个Encr ...

  2. Design Pattern: Visitor and Acyclic Visitor and their differences

    Design Pattern 笔记 Visitor and Acyclic Visitor 小记 extensibility, behavioral 前言 在Design Pattern上面学习设计模 ...

  3. 行为模式之Visitor模式

    1.意图 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作 2.适用性 (1)一个对象结构包含很多类对象,它们有不同的接口,而你想对这些实施一些 ...

  4. 设计模式--访问器(Visitor)模式

    模式定义 表示一个作用于某对象结构中的各元素的操作,使得可以在不改变(稳定)各元素的类的前提下定义(扩展)作用于这些元素的新操作(变化) 类图 要点总结 Visitor模式通过所谓双重分发(doubl ...

  5. 设计模式学习笔记——访问者(Visitor)模式

    设计模式学习笔记--访问者(Visitor)模式 @(设计模式)[设计模式, 访问者模式, visitor] 设计模式学习笔记访问者Visitor模式 基本介绍 访问者案例 类图 实现代码 Visit ...

  6. 设计模式 - Visitor 模式(访问者模式)

    作用:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.  UML结构图: 解析: Visitor模式把对结点的访问封装成一个抽象基类,通过派生 ...

  7. Visitor模式学习

    意图: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 似乎理解很麻烦,其实说白了,就是动态的给已经写好的代码(类)加入新的功能! 当然,首 ...

  8. 设计模型之Visitor模式-图书馆管理系统应用C++实现

    今天看到<<软件设计师>>面向对象第七章讲到几种设计模式,其中一种为Visitor模式.这种设计模式通过访问者对象的建立,在访问过程中将访问者作为参数传到被访问对象的函数中,实 ...

  9. 设计模式学习笔记--访问者(Visitor)模式

    写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式:每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案:当我们碰到模式 ...

最新文章

  1. 李彦宏乌镇谈人工智能:百度会很快和雄安宣布一个大的智能城市计划
  2. 计算机网络——OSI与TCPIP体系架构、功能及协议
  3. linux 线程 pthread_create 源码 剖析
  4. vue2.0 -- watch监听
  5. python中文件操作中不同的文件操作有何差异_Python学习基础篇 -6: Python中的文件操作...
  6. 2013.10u-boot移植之增加nand保存环境变量
  7. 解决:Connect to xx.xx.xxx.xx :8081 [/xx.xx.xx.xx] failed: Connection refu sed: connect -> [H
  8. WBOLT 搜索推送管理插件(原百度推送管理插件) 3.4.11 Pro
  9. oracle监听管理工具,oracle监听器管理
  10. 关于“指针数组”和”数组指针“
  11. paip.文件搜索工具总结V2012.8.18
  12. 分享一个NI软件卸载工具
  13. CreateThread()与_beginthread()的区别详细解析
  14. java生成zipf分布_统计分布-Zipf分布
  15. 计算机加法器原理,加法器原理
  16. linux主机独立显卡切换,Linux Deepin 2013 设置双显卡之关闭独显
  17. 科学数学工程工具MATLAB软件2023a中文版下载安装,MATLAB特色
  18. LZY踢石头(优先队列)
  19. 脚手架创建遇到报错:Error: command failed: pnpm install --reporter silent --shamefully-hoist
  20. 杰瑞学Perl之多值比较问题

热门文章

  1. 新装linux系统环境配置
  2. 计算机如何连接网络扫描仪,如何添加局域网网络扫描仪
  3. 实战!Python常见的几种数据可视化案例
  4. Linux中如何让命令在后台运行
  5. 如何用ADB命令删除Android中的系统应用
  6. 覃卫平java,广西外国语学院与柳州市柳江区实验高中、柳城县中学签订优质生源基地协议并圆满完成挂牌仪式...
  7. Linux系统的登录方式
  8. 制作一个属于自己的BHO吧!(C#)
  9. 这10个免费配图网站收好咯!(可商用)
  10. iOS支付宝、微信支付