設計模式之訪問者模式(visitor)
阿新 • • 發佈:2018-12-16
1、定義
在訪問者模式(Visitor Pattern)中,我們使用了一個訪問者類,它改變了元素類的執行演算法。通過這種方式,元素的執行演算法可以隨著訪問者改變而改變。這種型別的設計模式屬於行為型模式。根據模式,元素物件已接受訪問者物件,這樣訪問者物件就可以處理元素物件上的操作。
2、介紹
優點: 1、符合單一職責原則。 2、優秀的擴充套件性。 3、靈活性。
缺點: 1、具體元素對訪問者公佈細節,違反了迪米特原則。 2、具體元素變更比較困難。 3、違反了依賴倒置原則,依賴了具體類,沒有依賴抽象。
使用場景: 1、物件結構中物件對應的類很少改變,但經常需要在此物件結構上定義新的操作。 2、需要對一個物件結構中的物件進行很多不同的並且不相關的操作,而需要避免讓這些操作"汙染"這些物件的類,也不希望在增加新操作時修改這些類。
注意事項:訪問者可以對功能進行統一,可以做報表、UI、攔截器與過濾器。
3、原始碼
類關係圖:
運用到知識點:將容器中元素型別定義為父類指標,可以在容器中放入子類指標。
3.1、標頭檔案
IVisitor.h
#pragma once #include<iostream> 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<iostream> 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 <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;
};
CommonEmployee.h
#include "employee.h"
#include "IVisitor.h"
#include <iostream>
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 <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("性別:");
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 <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);
}
CommonEmployee.cpp
#include "CommonEmployee.h"
#include <iostream>
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