设计模式之访问者模式(visitor)

1、定义

在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。

2、介绍

优点: 1、符合单一职责原则。 2、优秀的扩展性。 3、灵活性。

缺点: 1、具体元素对访问者公布细节,违反了迪米特原则。 2、具体元素变更比较困难。 3、违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

使用场景: 1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。 2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。

注意事项:访问者可以对功能进行统一,可以做报表、UI、拦截器与过滤器。

3、源码

类关系图:

设计模式之访问者模式(visitor)_第1张图片

 运用到知识点:将容器中元素类型定义为父类指针,可以在容器中放入子类指针。

3.1、头文件

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;
};

3.2、实现

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

4、结果

设计模式之访问者模式(visitor)_第2张图片

 

你可能感兴趣的:(C++)