在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。
优点: 1、符合单一职责原则。 2、优秀的扩展性。 3、灵活性。
缺点: 1、具体元素对访问者公布细节,违反了迪米特原则。 2、具体元素变更比较困难。 3、违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
使用场景: 1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。 2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
注意事项:访问者可以对功能进行统一,可以做报表、UI、拦截器与过滤器。
类关系图:
运用到知识点:将容器中元素类型定义为父类指针,可以在容器中放入子类指针。
IVisitor.h
#pragma once
#include
using namespace std;
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
using namespace std;
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);
};
Employee.h
#pragma once
#include "IVisitor.h"
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;
};
Manager.h
#pragma once
#include "employee.h"
#include "IVisitor.h"
#include
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;
};
CommonEmployee.h
#include "employee.h"
#include "IVisitor.h"
#include
using std::string;
class CCommonEmployee :
public CEmployee
{
public:
CCommonEmployee(void);
~CCommonEmployee(void);
string GetJob();
void SetJob(string job);
void Accept(IVisitor *pVisitor);
protected:
string GetOtherInfo();
private:
string m_job;
};
BaseVisitor.cpp
#include "BaseVisitor.h"
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;
}*/
#define _CRT_SECURE_NO_WARNINGS
#include "BaseVisitor.h"
#include
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("性别:");
int getsex = pemployee->GetSex();
char c[32];
//itoa(getsex, c,10);
sprintf(c, "%d", getsex);
info.append(c);
info.append("\t");
info.append("薪水:");
getsex = pemployee->GetSalary();
//itoa(getsex, c, 10);
char c1[64]="0";
sprintf(c1,"%d",getsex);
info.append(c1);
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.cpp
#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.cpp
#include "Manager.h"
#include
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);
}
CommonEmployee.cpp
#include "CommonEmployee.h"
#include
using std::string;
CCommonEmployee::CCommonEmployee(void)
{
this->m_job = "";
}
CCommonEmployee::~CCommonEmployee(void)
{
}
string CCommonEmployee::GetJob()
{
return this->m_job;
}
void CCommonEmployee::SetJob(string job)
{
this->m_job = job;
}
string CCommonEmployee::GetOtherInfo()
{
string job = "";
job.append("工作:");
job.append(this->m_job);
job.append("\t");
return job;
}
void CCommonEmployee::Accept(IVisitor *pVisitor)
{
pVisitor->Visit(*this);
}
Visitor.cpp