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

作用

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

类视图

实现

访问者模式的关键实现是在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. Vuejs——(11)组件——slot内容分发

    版权声明:出处http://blog.csdn.net/qq20004604   目录(?)[+]   本篇资料来于官方文档: http://cn.vuejs.org/guide/components ...

  2. 利用ADO打开Access数据(64位系统)

    64位的access一定要用64的程序才能正确打开,仍然用"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Test.accdb;Persist ...

  3. H5的Page Visibility API

    概述 哈哈,又学了一个H5的API.今天突然对动态获取网页的选中状态很感兴趣,然后去查了下,发现真的有个API控制它--Page Visibility API.于是把学到的东西记录下来,供以后开发时参 ...

  4. css font-family属性设置中文字体乱码

    一般设置字体,个人都喜欢用中文,比如:font-family:"微软雅黑":但是偶尔会出现设置以后字体显示乱码的问题 解决方法[1]: 看看你的CSS文件的第一行有没有:@char ...

  5. C语言中全局结构体指针隐含的错误

    前天在嵌入式系统上,调试一个数组的全局变量时,发现该变量一直会动态变化.深入分析, 才发现该全局结构体没有申请内存,而是用了一个指针.这种情况编译器是检查不出来的,在linux 上运行会挂掉,但是在裸 ...

  6. vue 所有的指令

    1. v-text v-text主要用来更新textContent,可以等同于JS的text属性. <span v-text="msg"></span> 这 ...

  7. Centos6.5安装Python2.7.9

    1. 问题背景 Centos6.5默认自带的python环境是2.6.6,python的一些特性没法使用,所以要对python进行升级,借鉴了网上其他同学的安装教程,但是还是遇到一些坑,不是那木顺利, ...

  8. LeetCode--No.001 Two Sum

    Two Sum Total Accepted: 262258 Total Submissions: 1048169 Difficulty: Easy Given an array of integer ...

  9. Asp.net core 跨域设置

    验证环境: dotnet core 2.1/Asp.net core2.1 一.作用域在中间件层  配置的方式是在startup.cs文件Configure(IApplicationBuilder a ...

  10. Cordova安装、设置代理和引入插件

    cardova代理 $ npm config --global set registry http://registry.cnpmjs.org cardova添加插件 格式:cordova plugi ...