访问者模式(Visitor)是一种分离对象数据结构与行为的方法,通过这种分离,可以为一个已存在的类或类群增加新的操作而无需为它们作任何修改。 结构图为:
公司的人事评估需要人事部访问每一个员工列表,逐个对员工作出评估,人事部有两个访问者,一个访问者评估员工假期,另一个评估员工薪资。
实现代码:
//Element.h
class Visitor;
class Element
{
public:
Element();
virtual ~Element();
virtual void Accept(Visitor*) = 0;
friend class Visitor;
};
//Element.cpp
#include "stdafx.h"
#include "Element.h"
Element::Element()
{
}
Element::~Element()
{
}
//Employee.h
#include "Element.h"
class Employee : public Element
{
public:
Employee(char*, double, int);
virtual ~Employee();
void Accept(Visitor*);
char* GetName();
double GetSalary();
int GetVacationDays();
void SetSalary(double);
void SetVacationDays(int);
private:
char* m_pName;
double m_dSalary;
int m_nVacationDays;
};
//Employee.cpp
#include "stdafx.h"
#include "Employee.h"
#include "Visitor.h"
Employee::Employee(char* pName, double dSalary, int nVacationDays)
{
m_pName = pName;
m_dSalary = dSalary;
m_nVacationDays = nVacationDays;
}
Employee::~Employee()
{
}
void Employee::Accept(Visitor* pVisitor)
{
pVisitor->Visit(this);
}
char* Employee::GetName()
{
return m_pName;
}
double Employee::GetSalary()
{
return m_dSalary;
}
int Employee::GetVacationDays()
{
return m_nVacationDays;
}
void Employee::SetSalary(double dSalary)
{
m_dSalary = dSalary;
}
void Employee::SetVacationDays(int nVacationDays)
{
m_nVacationDays = nVacationDays;
}
//Visitor.h
class Element;
class Visitor
{
public:
virtual ~Visitor() = 0;
virtual void Visit(Element*) = 0;
protected:
Visitor();
};
//Visitor.cpp
#include "stdafx.h"
#include "Visitor.h"
Visitor::Visitor()
{
}
Visitor::~Visitor()
{
}
//IncomeVisitor.h
#include "Visitor.h"
class IncomeVisitor : public Visitor
{
public:
IncomeVisitor();
virtual ~IncomeVisitor();
void Visit(Element*);
};
//IncomeVisitor.cpp
#include "stdafx.h"
#include "IncomeVisitor.h"
#include "Employee.h"
#include <iostream>
using namespace std;
IncomeVisitor::IncomeVisitor()
{
}
IncomeVisitor::~IncomeVisitor()
{
}
void IncomeVisitor::Visit(Element* pElement)
{
//访问者提高员工10%的薪资
Employee* pEmployee = static_cast<Employee*>(pElement);
double dSalary = pEmployee->GetSalary();
pEmployee->SetSalary(dSalary * 1.10);
cout << "员工 " << pEmployee->GetName()
<< " 的新工资是:" << pEmployee->GetSalary() << "元" << endl;
}
//VacationVisitor.h
#include "Visitor.h"
class VacationVisitor : public Visitor
{
public:
VacationVisitor();
virtual ~VacationVisitor();
void Visit(Element*);
};
//VacationVisitor.cpp
#include "stdafx.h"
#include "VacationVisitor.h"
#include "Employee.h"
#include <iostream>
using namespace std;
VacationVisitor::VacationVisitor()
{
}
VacationVisitor::~VacationVisitor()
{
}
void VacationVisitor::Visit(Element* pElement)
{
//访问者为员工增加3天假期
Employee* pEmployee = static_cast<Employee*>(pElement);
int nVacationDays = pEmployee->GetVacationDays();
pEmployee->SetVacationDays(nVacationDays + 3);
cout << "员工 " << pEmployee->GetName()
<< " 的新假期是:" << pEmployee->GetVacationDays() << "天" << endl;
}
//main.cpp
#include "stdafx.h"
#include "Employee.h"
#include "IncomeVisitor.h"
#include "VacationVisitor.h"
int main(int argc, char* argv[])
{
Element* pEmployeeA = new Employee("张三", 10000.00, 10);
Element* pEmployeeB = new Employee("李四", 15000.00, 20);
IncomeVisitor incomeV;
VacationVisitor vacationV;
incomeV.Visit(pEmployeeA);
vacationV.Visit(pEmployeeB);
return 0;
}
代码中,我们通过访问者(IncomeVisitor、VacationVisitor)对员工张三与李四进行评估,并给张三增加10%的工资,给李四增加3天假期。
最后输出为:
员工 张三 的新工资是:11000元
员工 李四 的新假期是:23天