访问者模式是一种将数据操作和数据结构分离的设计模式,可以说是面向数据密集型的一种设计方式,数据的结构相对稳定,有明显的分层和分类,而对数据对象的相关操作进行分组、分析等二次加工,这些操作都是由访问者来执行的,而不是将这些放到被访问的数据对象中,方便了操作方法的扩展。

作用

封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。

类视图

实现

访问者模式的关键实现是在Element中的accept函数,该函数传入visitor,并在函数内调用visitor的针对该对象的方法,访问者调用元素类中的方法,又回到访问类中进行调用的方式叫做双重分派。

class Person
// 游乐设施
class Facility
{
public:
Facility():m_ncost_money(0), m_ncost_time(0){}
virtual void accept( Person*) =0;
virtual int SpendMoney()=0;
virtual int SpendTime()=0;
protected:
int m_ncost_money;
int m_ncost_time;
}; //摩天轮
class FerrisWheel : public Facility
{
public:
FerrisWheel():m_ncost_money(10), m_ncost_time(15){}
void accept( Person* persion)
{
persion->play(this);
}
int SpendMoney(){ return m_ncost_time;}
int SpendTime(){return m_ncost_money;}
};
//碰碰车
class BumperCar : public Facility
{
public:
BumperCar():m_ncost_money(30), m_ncost_time(10){}
void accept( Person* persion)
{
persion->play(this);
}
int SpendMoney(){ return m_ncost_time;}
int SpendTime(){return m_ncost_money;}
};
//过山车
class RollerCoaster : public Facility
{
public:
RollerCoaster():m_ncost_money(100), m_ncost_time(20){}
void accept( Person* persion)
{
persion->play(this);
}
int SpendMoney(){ return m_ncost_time;}
int SpendTime(){return m_ncost_money;}
}; class Person
{
public:
Person() : m_nToTalMoney(0),m_nToTalTime(0){}
void Play(FerrisWheel*);
void Play(BumperCar*);
void Play(FerrisWheel*);
public:
int GetTotalMoney()
{
return m_nToTalMoney;
}
int GetTotalTime()
{
return m_nToTalTime;
}
protected:
int m_nToTalMoney;
int m_nToTalTime; } class Adult : public Person
{
public:
void Play(FerrisWheel* ferriswheel)
{
int nMoney = ferriswheel->SpendMoney();
m_ncost_money+=nMoney;
int nTime = ferriswheel->SpendTime();
m_nToTalTime += nTime;
}
void Play(BumperCar* bumpercar)
{
int nMoney = BumperCar->SpendMoney();
m_ncost_money+=nMoney;
int nTime = BumperCar->SpendTime();
m_nToTalTime += nTime;
}
void Play(RollerCoaster* rollercoaster)
{
int nMoney = RollerCoaster->SpendMoney();
m_ncost_money+=nMoney;
int nTime = RollerCoaster->SpendTime();
m_nToTalTime += nTime;
} };
//儿童所有花费半价
class Childen : public Person
{
public:
void Play(FerrisWheel* ferriswheel)
{
int nMoney = ferriswheel->SpendMoney()/2;
m_ncost_money+=nMoney;
int nTime = ferriswheel->SpendTime();
m_nToTalTime += nTime;
}
void Play(BumperCar* bumpercar)
{
int nMoney = BumperCar->SpendMoney()/2;
m_ncost_money+=nMoney;
int nTime = BumperCar->SpendTime();
m_nToTalTime += nTime;
}
void Play(RollerCoaster* rollercoaster)
{
int nMoney = RollerCoaster->SpendMoney()/2;
m_ncost_money+=nMoney;
int nTime = RollerCoaster->SpendTime();
m_nToTalTime += nTime;
}
}; int main()
{
FerrisWheel fw;
BumperCar bc;
RollerCoaster rc; Childen son;
Adult mather;
//儿子玩了所有项目
son.play(fw);
son.play(bc);
son.play(rc);
//可怜的妈妈只陪儿子玩了一个过山车
mother.play(rc); int nSonCostMoney = son.GetTotalMoney();
int nSonCostTime = son.getTotalTime();
int nMotherCostMoney = mother.GetTotalMoney();
int nMotherCostTime = mother.getTotalTime(); cout<< "Son spend money :" << nSonCostMoney << " spend time: "<< nSonCostTime; << endl;
cout<< "Mother spend money :" << nMotherCostMoney << " Mother time: "<< nMotherCostTime; << endl; }

访问者模式的主要问题是因为每个访问者需要有对应的方法来处理每一种可能的具体数据,,那么一旦实现了访问者模式,其具体类的数量和类型就不能轻易被改变。

应用场景

  1. 对象结构比较稳定,但经常需要在此对象结构上定义新的操作。
  2. 需要对一个对象结构中的对象进行很多不同的且不相关的操作,而需要避免这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。

设计模式之访问者模式(Visitor )的更多相关文章

  1. 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern)

    原文:乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) 作者:webabc ...

  2. 二十四种设计模式:访问者模式(Visitor Pattern)

    访问者模式(Visitor Pattern) 介绍表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 示例有一个Message实体类,某些对象对 ...

  3. [设计模式] 23 访问者模式 visitor Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对访问者模式是这样说的:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.访问 ...

  4. 设计模式(17) 访问者模式(VISITOR) C++实现

    意图: 表示一个作用于某对象结构的各元素的操作.它使你可以再不改变各元素的类的前提下定义作用于这些元素的新操作. 动机: 之前在学校的最后一个小项目就是做一个编译器,当时使用的就是访问者模式. 在静态 ...

  5. 【设计模式】—— 访问者模式Visitor

    前言:[模式总览]——————————by xingoo 模式意图 对于某个对象或者一组对象,不同的访问者,产生的结果不同,执行操作也不同.此时,就是访问者模式的典型应用了. 应用场景 1 不同的子类 ...

  6. 行为型设计模式之访问者模式(Visitor)

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

  7. 设计模式 ( 二十 ) 访问者模式Visitor(对象行为型)

    设计模式 ( 二十 ) 访问者模式Visitor(对象行为型) 1.概述 在软件开发过程中,对于系统中的某些对象,它们存储在同一个集合collection中,且具有不同的类型,而且对于该集合中的对象, ...

  8. 访问者模式 Visitor 行为型 设计模式(二十七)

    访问者模式 Visitor    <侠客行>是当代作家金庸创作的长篇武侠小说,新版电视剧<侠客行>中,开篇有一段独白:  “茫茫海外,传说有座侠客岛,岛上赏善罚恶二使,每隔十年 ...

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

    设计模式:访问者(Visitor)模式 一.前言    什么叫做访问,如果大家学过数据结构,对于这点就很清晰了,遍历就是访问的一般形式,单独读取一个元素进行相应的处理也叫作访问,读取到想要查看的内容+ ...

  10. 北风设计模式课程---访问者模式(Visitor)

    北风设计模式课程---访问者模式(Visitor) 一.总结 一句话总结: 设计模式是日常问题的经验总结方案,所以学好设计模式对日常出现的问题可以有很好的解决. 访问者设计模式有点神似 抽象工厂模式, ...

随机推荐

  1. .NET MVC 学习笔记(一)— 新建MVC工程

    一..NET MVC 学习笔记(一)—— 新建MVC工程 接触MVC有段时间了,一直想找机会整理一下,可是限于文笔太差,所以一直迟迟羞于下手,想到最近做过的MVC项目也有一些了,花点时间整理一下方便以 ...

  2. Thinking in Java Chapter 14

    From Thinking in Java 4th Edition RTTI(Run-Time Type Information),运行时类型信息,使得你可以在程序运行时发现和使用类型信息.对RTTI ...

  3. Objective-C优缺点

    优点: 1:Category,使用category可以在不改变原来类的同时为类增加新的方法或者重写原来类的方法实现(使用runtime方法还可以在分类中实现方法交换和添加属性操作) 2:运行时 动态识 ...

  4. [W3bSafe]Metasploit溢出渗透内网主机辅助脚本

    文章来源i春秋 脚本用Shell编写  有的内网特别脆弱  本脚本主要就是 测试的话方便一点   输入内网网关就能调用Metasploit全部模块测试整个内网 运行截图<ignore_js_op ...

  5. 开源播放器 ijkplayer (一) :使用Ijkplayer播放直播视频

    1.ijkplayer 编码 IjkPlayer支持硬解码和软解码. 软解码时不会旋转视频角度这时需要你通过onInfo的what == IMediaPlayer.MEDIA_INFO_VIDEO_R ...

  6. Bootstrap轮播如何支持移动端左右滑动

    一直觉得bootstrap的轮播用起来很好用,代码简单,又支持响应式,不过从来没想过,也不知道原来bootstrap的轮播竟然不支持在手机上左右滑动 解决方法就是:使用滑动手势js插件:hammer. ...

  7. HttpClient实现HTTP文件通用下载类

    import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import org.apache. ...

  8. 25-socket

    socket通信流程 #server端 #family参数代表地址家族,可为AF_INET或AF_UNIX.AF_INET家族包括#Internet地址,AF_UNIX家族用于同一台机器上的进程间通信 ...

  9. 我是如何利用Github Pages搭建起我的博客,细数一路的坑

    1.前言 其实早在这之前我就一直想过写博客,但由于种种原因一直没有去学习这方面的知识,最近半个月(从开始动手到搭建好)一直陆陆续续的在着手这方面的工作.从开始到搭建完成的过程中遇到了很多困难,因为在这 ...

  10. Postgresql操作json格式数据

    1.select array_to_json('{{1,5},{99,100}}'::int[])