18.1.解释

概念:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

main(),客户

IVisitor,访问者接口

CBaseVisitor,访问者实现类

CEmployee,被访问者抽象类

CCommonEmployee,被访问者实现类之一

CManager,被访问者实现类之二

说明:A接受B的访问,B主动的执行访问动作。

注意:和观察者的区别是,被观察者要执行一个动作,然后主动发送通知给观察者。访问者模式是由访问者主动发出的动作。

看代码:

//IVisitor.h
#pragma once class CCommonEmployee;
class CManager;
class IVisitor
{
public: IVisitor(void)
{
} virtual ~IVisitor(void)
{
}
virtual void Visit(CCommonEmployee commonEmployee) = 0;
virtual void Visit(CManager manager) = 0;
virtual int GetTotalSalary() = 0;
}; //BaseVisitor.h
#pragma once
#include "ivisitor.h"
#include "CommonEmployee.h"
#include "Manager.h"
#include <iostream>
using std::string;
class CBaseVisitor :
public IVisitor
{
public:
CBaseVisitor(void);
~CBaseVisitor(void);
void Visit(CCommonEmployee commonEmployee);
void Visit(CManager manager);
int GetTotalSalary();
private:
string GetBasicInfo(CEmployee *pemployee);
string GetManagerInfo(CManager manager);
string GetCommonEmployee(CCommonEmployee employee);
static const int MANAGER_COEFFICENT = 5;
static const int COMMONEMPLOYEE_COEFFICENT = 2;
int m_commonTotal;
int m_managerTotal;
void CalCommonSalary(int salary);
void CalManagerSalary(int salary);
}; //BaseVisitor.cpp
#include "StdAfx.h"
#include "..\CommonDeclare\Convert.h"
#include "BaseVisitor.h"
#include <iostream>
using std::string;
using std::cout;
using std::endl; CBaseVisitor::CBaseVisitor(void)
{
m_commonTotal = 0;
m_managerTotal = 0;
} CBaseVisitor::~CBaseVisitor(void)
{
} void CBaseVisitor::Visit(CCommonEmployee commonEmployee)
{
cout << this->GetCommonEmployee(commonEmployee).c_str() << endl;
this->CalCommonSalary(commonEmployee.GetSalary());
} void CBaseVisitor::Visit(CManager manager)
{
cout << this->GetManagerInfo(manager).c_str() << endl;
this->CalManagerSalary(manager.GetSalary());
} string CBaseVisitor::GetBasicInfo(CEmployee *pemployee)
{
string info = "";
info.append("姓名:");
info.append(pemployee->GetName());
info.append("\t");
info.append("性别:");
info.append(CConvert::ToString(pemployee->GetSex()));
info.append("\t");
info.append("薪水:");
info.append(CConvert::ToString(pemployee->GetSalary()));
info.append("\t");
return info;
} string CBaseVisitor::GetManagerInfo(CManager manager)
{
string basicInfo = this->GetBasicInfo(&manager);
string otherInfo = "";
otherInfo.append("业绩:");
otherInfo.append(manager.GetPerformance());
otherInfo.append("\t");
basicInfo.append(otherInfo);
return basicInfo;
} string CBaseVisitor::GetCommonEmployee(CCommonEmployee employee)
{
string basicInfo = this->GetBasicInfo(&employee);
string otherInfo = "";
otherInfo.append("工作:");
otherInfo.append(employee.GetJob());
otherInfo.append("\t");
basicInfo.append(otherInfo);
return basicInfo;
} int CBaseVisitor::GetTotalSalary()
{
return this->m_commonTotal + this->m_managerTotal;
} void CBaseVisitor::CalCommonSalary(int salary)
{
this->m_commonTotal += salary;
} void CBaseVisitor::CalManagerSalary(int salary)
{
this->m_managerTotal += salary;
}
//Employee.h
#pragma once
#include "IVisitor.h"
#include <iostream>
using std::string;
class CEmployee
{
public:
static int MALE;
static int FEMALE;
CEmployee(void);
virtual ~CEmployee(void);
string GetName();
void SetName(string name);
int GetSalary();
void SetSalary(int v);
int GetSex();
void SetSex(int v);
virtual void Accept(IVisitor *pVisitor) = 0;
private:
string m_name;
int m_salary;
int m_sex;
}; //Employee.cpp
#include "StdAfx.h"
#include "Employee.h"
int CEmployee::MALE = 0;
int CEmployee::FEMALE = 1; CEmployee::CEmployee(void)
{
} CEmployee::~CEmployee(void)
{
} string CEmployee::GetName()
{
return m_name;
} void CEmployee::SetName( string name )
{
m_name = name;
} int CEmployee::GetSalary()
{
return m_salary;
} void CEmployee::SetSalary( int v )
{
m_salary = v;
} int CEmployee::GetSex()
{
return m_sex;
} void CEmployee::SetSex( int v )
{
m_sex = v;
} //Manager.h
#pragma once
#include "employee.h"
#include "IVisitor.h"
#include <iostream>
using std::string;
class CManager :
public CEmployee
{
public:
CManager(void);
~CManager(void);
string GetPerformance();
void SetPerformance(string per);
void Accept(IVisitor *pVisitor);
protected:
string GetOtherInfo();
private:
string m_performance;
}; //Manager.cpp
#include "StdAfx.h"
#include "Manager.h"
#include <iostream>
using std::string; CManager::CManager(void)
{
this->m_performance = "";
} CManager::~CManager(void)
{
} string CManager::GetPerformance()
{
return m_performance;
} void CManager::SetPerformance(string per)
{
this->m_performance = per;
} string CManager::GetOtherInfo()
{
string info = "";
info.append("业绩:");
info.append(this->m_performance);
info.append("\t");
return info;
} void CManager::Accept(IVisitor *pVisitor)
{
pVisitor->Visit(*this);
} // Visitor.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Employee.h"
#include "CommonEmployee.h"
#include "Manager.h"
#include "BaseVisitor.h"
#include "..\CommonDeclare\Convert.h"
#include <vector>
#include <iostream>
using std::vector;
using std::cout;
using std::endl; void MockEmployee(vector<CEmployee*> *pvce)
{
CCommonEmployee *pZhangSan = new CCommonEmployee();
pZhangSan->SetJob("编写Java程序,绝对的蓝领、苦工加搬运工");
pZhangSan->SetName("张三");
pZhangSan->SetSalary(1800);
pZhangSan->SetSex(CEmployee::MALE);
pvce->push_back(pZhangSan); CCommonEmployee *pLiSi = new CCommonEmployee();
pLiSi->SetJob("页面美工,审美素质太不流行了!");
pLiSi->SetName("李四");
pLiSi->SetSalary(1900);
pLiSi->SetSex(CEmployee::FEMALE);
pvce->push_back(pLiSi); CManager *pWangWu = new CManager();
pWangWu->SetPerformance("基本上是负值,但是我会拍马屁呀");
pWangWu->SetName("王五");
pWangWu->SetSalary(1900);
pWangWu->SetSex(CEmployee::FEMALE);
pvce->push_back(pWangWu);
} void DoIt()
{
vector<CEmployee*> vce;
MockEmployee(&vce);
vector<CEmployee*>::const_iterator readIt = vce.begin(); CBaseVisitor visitor;
for (; readIt != vce.end(); readIt ++)
{
(*readIt)->Accept(&visitor);
}
cout << "本公司的月工资总额是:" << CConvert::ToString(visitor.GetTotalSalary()).c_str() << endl; vector<CEmployee*>::reverse_iterator delIt = vce.rbegin();
for (; delIt != vce.rend(); delIt++)
{
delete (*delIt);
(*delIt) = NULL;
}
vce.clear();
} int _tmain(int argc, _TCHAR* argv[])
{
DoIt();
return 0;
}

访问者模式属于行为型模式。访问者模式是由访问者主动发出的动作。

设计模式C++学习笔记之十八(Visitor访问者模式)的更多相关文章

  1. 设计模式C++学习笔记之十(Builder建造者模式)

      建造者模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.一段晦涩难懂的文字,实现创建不同表示的方法就是给创建的过程传入创建的参数.详细的还是看代码吧. 10.1.解释 ...

  2. Java框架spring 学习笔记(十八):事务管理(xml配置文件管理)

    在Java框架spring 学习笔记(十八):事务操作中,有一个问题: package cn.service; import cn.dao.OrderDao; public class OrderSe ...

  3. Android学习笔记(十八)——再谈升级数据库

    //此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 之前我们为了保证数据库中的表是最新的,只是简单地在 onUpgrade()方法中删除掉了当前所有的表,然后强制 ...

  4. Dynamic CRM 2013学习笔记(十八)根据主表状态用JS控制子表自定义按钮

    有时要根据主表的审批状态来控制子表上的按钮要不要显示,比如我们有一个需求审批通过后就不能再上传文件了. 首先打开Visual Ribbon Editor, 如下图,我们可以利用Enable Rules ...

  5. Java学习笔记二十八:Java中的接口

    Java中的接口 一:Java的接口: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承 ...

  6. angular学习笔记(二十八-附2)-$http,$resource中的promise对象

    下面这种promise的用法,我从第一篇$http笔记到$resource笔记中,一直都有用到: HttpREST.factory('cardResource',function($resource) ...

  7. Java学习笔记(十八)——Java DTO

    [前面的话] 在和技术人员的交流中,各种专业术语会出现,每次都是默默的记录下出现的术语,然后再去网上查看是什么意思.最近做项目,需要使用到DTO,然后学习一下吧. 这篇文章是关于Java DTO的,选 ...

  8. Java基础学习笔记二十八 管家婆综合项目

    本项目为JAVA基础综合项目,主要包括: 熟练View层.Service层.Dao层之间的方法相互调用操作.熟练dbutils操作数据库表完成增删改查. 项目功能分析 查询账务 多条件组合查询账务 添 ...

  9. 设计模式C++学习笔记之十九(State状态模式)

      19.1.解释 概念:允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. main(),客户 CLiftState,电梯状态抽象类 CCloseingState,电梯门关闭 ...

随机推荐

  1. appserver WildFly 8.1 / jboss debug / jboss rmi

    s 开启jboss debug模式,服务端口8787. [jbossuser@lindowsdevapp04 ~]$ vim /opt/wildfly/bin/standalone.conf JAVA ...

  2. C# enum、int、string三种类型互相转换

    enum.int.string三种类型之间的互转 #代码: public enum Sex { Man=, Woman= } public static void enumConvert() { in ...

  3. Java NIO系列教程(七) selector原理 Epoll版的Selector

    目录: Reactor(反应堆)和Proactor(前摄器) <I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor> <[转]第8章 前摄器(Proa ...

  4. 利用 JMetal 实现大规模聚类问题的研究(一)JMetal配置

    研究多目标优化问题,往往需要做实验来对比效果,所以需要很多多目标方面的经典代码,比如NSGA-II, SPEA, MOEA,MOEA/D, 或者PSO等等. 想亲自实现这些代码,非常浪费时间,还有可能 ...

  5. 【1】【leetcode-93】复原IP地址

    (不会,典型) 给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式. 示例: 输入: "25525511135" 输出: ["255.255.11.135 ...

  6. IntelliJ IDEA 2017 配置Tomcat 运行Web项目

    以前都用MyEclipse写程序的 突然用了IDEA各种不习惯的说 借鉴了很多网上好的配置办法,感谢各位大神~ 前期准备 IDEA.JDK.Tomcat请先在自己电脑上装好 好么~ 博客图片为主 请多 ...

  7. javaScript ES5常考面试题总结

    js的六种原始值 boolean null undefined number string symbol 坑1: 首先原始类型存储的都是值,是没有函数可以调用的,比如 undefined.toStri ...

  8. 配置tomcat限制指定IP地址访问后端应用

    1. 场景后端存在N个tomcat实例,前端通过nginx反向代理和负载均衡. tomcat1      tomcatN         |                 |        |    ...

  9. 谷歌地图,国内使用Google Maps JavaScript API,国外业务

    目前还是得墙 <!DOCTYPE html> <html> <head> <meta name="viewport" content=&q ...

  10. Java动态代理 深度详解

    代理模式是设计模式中非常重要的一种类型,而设计模式又是编程中非常重要的知识点,特别是在业务系统的重构中,更是有举足轻重的地位.代理模式从类型上来说,可以分为静态代理和动态代理两种类型. 今天我将用非常 ...