访问者模式意图在不改变目标对象类结构的情况下,扩展对象类的行为。新扩展的行为均被封装成类对象的形式来动作。应用该模式时,往往目标类系与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一切乱码的解释 以及源头【转】

    工作中经常遇到java编码问题,由于缺乏研究,总是无法给出确切的答案,这个周末在网上查了一些资料,在此做些汇总. 问题一:在java中读取文件时应该采用什么编码? Java读取文件的方式总体可以分为两 ...

  2. Android系统默认Home应用程序(Launcher)的启动过程源码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还须要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...

  3. 将JDBC ResultSet结果集变成List

    private List<Map<String, Object>> list = new ArrayList<Map<String,Object>>() ...

  4. “too many open files" ----增大打开的文件数

     http://www.cnblogs.com/ibook360/archive/2012/05/11/2495405.html [root@localhost ~]# ab -n -c http:/ ...

  5. [转] Linux TCP/IP网络小课堂:net-tools与iproute2大比较

    PS:netstat选项是-planet,方便记忆 http://os.51cto.com/art/201409/450886.htm 如今许多系统管理员仍结合使用ifconfig.route.arp ...

  6. Ubuntu下全命令行安装Android SDK

    为了在AWS云服务器上实现自动化打包Android APP的APK包,我需要远程命令行环境下安装Android SDK,当然还要用代理或者科学上网,这里简单整理一下过程: 首先,由于墙的原因,Andr ...

  7. (转)织梦cms首页添加digg顶一下的修改方法

    现在把文章内容页拔的顶拔出来.分享一下让各位需要的朋友参考使用(特别注意:红色的是修改的地方)第一步:把顶踩的js和ajax提取出来,放在想要使用的页面用(比如:首页)以下是内容页顶踩用的js.提取出 ...

  8. 7——使用TextView实现跑马灯

    首先给TextView添加一个单行限制: android:singleLine="true" - 解决方案一 更改TextView的一个属性: android:ellipsize= ...

  9. eclise -The method onClick(View) of type new View.OnClickListener(){} must override a superclass method

    在做arcgis android开发的时候,突然遇到这种错误,The method onClick(View) of type new View.OnClickListener(){} must ov ...

  10. iOS开发之通知中心(NSNotificationCenter)

    前言 面向对象的设计思想是把行为方法封装到每一个对象中,以用来增加代码的复用性.正是这种分散封装,增加了对象之间的相互关联,总是有很多的对象需要彼此了解以及相互操作! 一个简单示例说明这种交互产生的对 ...