设计模式之访问者模式(Visitor )
访问者模式是一种将数据操作和数据结构分离的设计模式,可以说是面向数据密集型的一种设计方式,数据的结构相对稳定,有明显的分层和分类,而对数据对象的相关操作进行分组、分析等二次加工,这些操作都是由访问者来执行的,而不是将这些放到被访问的数据对象中,方便了操作方法的扩展。
作用
封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。
类视图

实现
访问者模式的关键实现是在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;
}
访问者模式的主要问题是因为每个访问者需要有对应的方法来处理每一种可能的具体数据,,那么一旦实现了访问者模式,其具体类的数量和类型就不能轻易被改变。
应用场景
- 对象结构比较稳定,但经常需要在此对象结构上定义新的操作。
- 需要对一个对象结构中的对象进行很多不同的且不相关的操作,而需要避免这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。
设计模式之访问者模式(Visitor )的更多相关文章
- 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern)
原文:乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) 作者:webabc ...
- 二十四种设计模式:访问者模式(Visitor Pattern)
访问者模式(Visitor Pattern) 介绍表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 示例有一个Message实体类,某些对象对 ...
- [设计模式] 23 访问者模式 visitor Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对访问者模式是这样说的:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.访问 ...
- 设计模式(17) 访问者模式(VISITOR) C++实现
意图: 表示一个作用于某对象结构的各元素的操作.它使你可以再不改变各元素的类的前提下定义作用于这些元素的新操作. 动机: 之前在学校的最后一个小项目就是做一个编译器,当时使用的就是访问者模式. 在静态 ...
- 【设计模式】—— 访问者模式Visitor
前言:[模式总览]——————————by xingoo 模式意图 对于某个对象或者一组对象,不同的访问者,产生的结果不同,执行操作也不同.此时,就是访问者模式的典型应用了. 应用场景 1 不同的子类 ...
- 行为型设计模式之访问者模式(Visitor)
结构 意图 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 适用性 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依 ...
- 设计模式 ( 二十 ) 访问者模式Visitor(对象行为型)
设计模式 ( 二十 ) 访问者模式Visitor(对象行为型) 1.概述 在软件开发过程中,对于系统中的某些对象,它们存储在同一个集合collection中,且具有不同的类型,而且对于该集合中的对象, ...
- 访问者模式 Visitor 行为型 设计模式(二十七)
访问者模式 Visitor <侠客行>是当代作家金庸创作的长篇武侠小说,新版电视剧<侠客行>中,开篇有一段独白: “茫茫海外,传说有座侠客岛,岛上赏善罚恶二使,每隔十年 ...
- 设计模式:访问者(Visitor)模式
设计模式:访问者(Visitor)模式 一.前言 什么叫做访问,如果大家学过数据结构,对于这点就很清晰了,遍历就是访问的一般形式,单独读取一个元素进行相应的处理也叫作访问,读取到想要查看的内容+ ...
- 北风设计模式课程---访问者模式(Visitor)
北风设计模式课程---访问者模式(Visitor) 一.总结 一句话总结: 设计模式是日常问题的经验总结方案,所以学好设计模式对日常出现的问题可以有很好的解决. 访问者设计模式有点神似 抽象工厂模式, ...
随机推荐
- MySQL常用内置变量
MySQL用很多常用的内置变量,掌握这些内置变量后对于我们快速获取当前MySQL的配置有很大帮助,下面就来列举几个常用的变量. 查看当前MySQL版本号信息.show variables like ...
- linux安装nodejs运行vue程序
linux安装nodejs运行vue程序 1.与node官网下载安装包 https://nodejs.org/zh-cn/download/ 6.上传到服务器,并解压 tar -xvf node-v1 ...
- 【详细】Android入门到放弃篇-YES OR NO-》各种UI组件,布局管理器,单元Activity
问:达叔,你放弃了吗? 答:不,放弃是不可能的,丢了Android,你会心疼吗?如果别人把你丢掉,你是痛苦呢?还是痛苦呢?~ 引导语 有人说,爱上一个人是痛苦的,有人说,喜欢一个人是幸福的. 人与人之 ...
- kubernetes集群搭建(7):常见问题及处理
尤其在创建pod的时候,会遇见各类问题,请通过下列命令来查看错误详情 kubectl describe pod xxxxxx 1.问题现象:镜像始终获取不下来 解决办法:为docker设置镜像源 [r ...
- C#基础-gc算法
众所周知,c++是需要程序员手动管理内存的,然而手动释放内存很容易被程序员遗漏,从而导致资源浪费或内存泄露.为解决这个问题,垃圾回收器诞生了,代替程序员自动管理内存的释放.至于gc算法则是垃圾回收器清 ...
- linux下应用程序性能剖分神器gprofiler-tools-安装和使用
最近在摆弄算法的的优化,需要剖分一下算法的瓶颈,就找了一些代码剖分工具,其中 gprofileer-tools是很不错的工具,gperftools时google开源的一款C++性能分析分析工具,git ...
- JS 实现九宫格算法
九宫格算法核心: 利用控件索引index计算出控件所在的行数和列数: 利用控件计算出left距离: 利用控件计算出top距离: 写特效时需要用到定位 公式: 行 row=parseInt(i/cols ...
- Java 8 停止维护,Java 9 难产,IDEA 2018 发布,还有……
祝大家五一劳动节快乐,工作顺利! 又到了总结上个月干货的时候了,这个月我们带来了各种Java技术干货,各种送书抽奖福利,各种面试题分享,各种最新动态资讯等. 5.1重磅活动 | 区块链免费送书 &am ...
- Liferay的一些应用领域
Liferay的用途是快速的部署内外站点,统一权限管理,开发Web热插拔插件,并不是所有系统都适合 不适合Liferay的一些应用领域: 1.独立认证.简单的系统,比如一些简单的增删改查:2.复杂业务 ...
- python(33)——【re模块】
re模块(正则表达式) 就其本质而言,正则表达式是一种小型的.高度专业化的编程语言 在Python中(它内嵌在python中),并通过re模块来实现,正则表达式被编译成一系列的字节码,然后由C编写的匹 ...