访问者模式意图在不改变目标对象类结构的情况下,扩展对象类的行为。新扩展的行为均被封装成类对象的形式来动作。应用该模式时,往往目标类系与Visitor类系是两个不同的类系,它们配合工作但维护是分开的,互不影响。每次扩展一个新行为时,需要新增加一个Visitor派生类。而目标类系只需要接受Visitor对象即可。模式的类关系图参考如下:

模式编码结构参考如下:

 namespace visitor
{
class Target;
class IVisitor
{
public:
// some code here........
virtual void doSomething(Target* pTarget) {
// do something here........
// such as: if (nullptr != pTarget) pTarget->........
} };//class IVisitor class ConcreteVisitor1 : public IVisitor
{
public:
// some code here........
virtual void doSomething(Target* pTarget) override {
// do something here........
// such as: if (nullptr != pTarget) pTarget->........
} };//class ConcreteVisitor1 class ConcreteVisitor2 : public IVisitor
{
public:
// some code here........
virtual void doSomething(Target* pTarget) override {// do something here........
// such as: if (nullptr != pTarget) pTarget->........
} };//class ConcreteVisitor2 class Target
{
public:
// some code here........
virtual void accept(IVisitor* pVisitor) {
// do something here........
// such as:
if (nullptr != pVisitor) {
pVisitor->doSomething(this);
}
} };//class Target class ConcreteTarget1 : public Target
{
public:
// some code here........
virtual void accept(IVisitor* pVisitor) override {
// do something here........
// such as:
if (nullptr != pVisitor) {
pVisitor->doSomething(this);
}
} };//class ConcreteTarget1 class ConcreteTarget2 : public Target
{
public:
// some code here........
virtual void accept(IVisitor* pVisitor) override {
// do something here........
// such as:
if (nullptr != pVisitor) {
pVisitor->doSomething(this);
}
} };//class ConcreteTarget2 }//namespace visitor

访问者模式编码结构参考

访问者模式在不改动原有类结构的情况下即可扩展类对象的新的行为且不改变原有结构,这在对象类结构比较固定且比较完善,但又需要或有可能会扩展一些特殊的行为操作时特别有用。尤其在设计工具库等场合,可适应考虑为将来可能的新业务变动预留接口。其实有玩过objective-c的人,在看到该模式时,可能会想到objective-c语言的一个技术:在使用别人封装的对象时,可以重新为该对象扩展新的接口,同样也是不需要改变别人封装的对象。其实这个技术与该模式的意图是类似的。

访问者模式的好处是显而易见的,其允许我们自由扩展新的行为特性,但这也是其重大缺点,因为势必会破坏对象的封装特性(当然,像C++这样的语言还有friend可用,对于该特性的破坏还有一定的挽回余地,但friend其实质上就已是在破坏封装特性了)。另外,由于Visitor类系的引入,系统中维护的类将增多,且无形当中也会增加一定量的Visitor类系的实例对象。再者,新扩展一个Target类系类型时,则有可能会让Visitor类系产生较大的改动(这个可能还需要视实际的项目设计者的设计方案而定)。

【行为型】Visitor模式的更多相关文章

  1. 完成C++不能做到的事 - Visitor模式

    拿着刚磨好的热咖啡,我坐在了显示器前.“美好的一天又开始了”,我想. 昨晚做完了一个非常困难的任务并送给美国同事Review,因此今天只需要根据他们提出的意见适当修改代码并提交,一周的任务就完成了.剩 ...

  2. Visitor模式,Decorator模式,Extension Object模式

    Modem结构 Visitor模式 对于被访问(Modem)层次结构中的每一个派生类,访问者(Visitor)层次中都有一个对应的方法. 从派生类到方法的90度旋转. 新增类似的Windows配置函数 ...

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

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

  4. 设计模式:基于线程池的并发Visitor模式

    1.前言 第二篇设计模式的文章我们谈谈Visitor模式. 当然,不是简单的列个的demo,我们以电商网站中的购物车功能为背景,使用线程池实现并发的Visitor模式,并聊聊其中的几个关键点. 一,基 ...

  5. Visitor 模式心得

    最近读到Visitor模式,还是一知半解的.偶然翻到Uncle Bob对该模式的推导过程,有所心得,和大家分享一下. Uncle Bob 的链接是: http://butunclebob.com/Ar ...

  6. Java 的双重分发与 Visitor 模式

    双重分发(Double Dispatch) 什么是双重分发? 谈起面向对象的程序设计时,常说起的面向对象的「多态」,其中关于多态,经常有一个说法是「父类引用指向子类对象」. 这种父类的引用指向子类对象 ...

  7. 【转载】完成C++不能做到的事 - Visitor模式

    原文: 完成C++不能做到的事 - Visitor模式 拿着刚磨好的热咖啡,我坐在了显示器前.“美好的一天又开始了”,我想. 昨晚做完了一个非常困难的任务并送给美国同事Review,因此今天只需要根据 ...

  8. 设计模式之——visitor模式

    visitor模式,又叫访问者模式,把结构和数据分开,编写一个访问者,去访问数据结构中的元素,然后把对各元素的处理全部交给访问者类.这样,当需要增加新的处理时候,只需要编写新的 访问者类,让数据结构可 ...

  9. Visitor模式(访问者设计模式)

    Visitor ? 在Visitor模式中,数据结构与处理被分离开来.我们编写一个表示"访问者"的类来访问数据结构中的元素, 并把对各元素的处理交给访问者类.这样,当需要增加新的处 ...

  10. Behavioral模式之Visitor模式

    1.意图 表示一个作用于某对象结构中的各元素的操作.它使你能够在不改变各元素的类的前提下定义作用于这些元素的新操作. 2.别名 无 3.动机 考虑一个编译器.他将源程序表示为一个抽象语法树.该编译器须 ...

随机推荐

  1. Java---类反射(1)---类反射入门和基础

    什么是类反射 ☆什么是反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方 ...

  2. SSL证书的分类(按功能)

    SSL证书的分类(按功能) 一.域名型证书 DV SSL DV SSL 证书是 Domain Validation SSL Certificate 英文全称的简写,翻译成中文是域名型 SSL证书 或 ...

  3. 怎么调试EXC_BAD_ACCESS错误

    当你遇到了一个EXC_BAD_ACCESS错误,我通常会给开发者几个建议: 1.在可执行选项中设置NSZombieEnabled参数,这有时会帮缩小问题的范围: 2.运行apple的内存检测工具,如  ...

  4. Node.js学习(7)----包

    包是在模块的基础上更深一步的抽象,Node.js的包类似于C/C++函数库或者Java/.NET的类库.它将独立的功能封装起来用于发布.更新.依赖管理和版本控制. Node.js的包是一个目录,其中包 ...

  5. jxl对excel删除行

    简单记录下: package com.pingan; import java.io.File; import java.util.regex.Matcher; import java.util.reg ...

  6. JAR WAR EAR包的区别

    jar包和war包的区别: war是一个web模块,其中需要包括WEB-INF,是可以直接运行的WEB模块.而jar一般只是包括一些class文件,在声明了Main_class之后是可以用java命令 ...

  7. Swift_UILabel

    一.初始化 // 初始化UIlabel,并设置frame //let labelOne = UILabel.init(frame: CGRect.init(x: 10, y: 20, width: 3 ...

  8. Struts2.xml中result type属性说明

    在struts2配置XML里,result中type属性有以下几种: 1.dispatcher:服务器跳转到前台,后面跟着可以是JSP.htm等等前台页面,默认是这种. 2.redirect:客户端跳 ...

  9. Swift-Dictionary

    1.字典写法 Dictionary<KeyType,ValueType>,KeyType是你想要储存的键,ValueType是你想要储存的值. 唯一的限制就是KeyType必须是可哈希的, ...

  10. [PWA] 17. Cache the photo

    To cache photo, You need to spreate cache db to save the photo. So in wittr example, we cache the te ...