#include "stdafx.h"
#include <iostream>
using namespace std;
class CEmployee;
class CProgrammer;
class CManager;
class CCEO;
class IVisitor{
public:
virtual void Visit(CEmployee* p) = 0;
virtual void Visit(CProgrammer* p) = 0;
virtual void Visit(CManager* p) = 0;
virtual void Visit(CCEO* p) = 0;
};
class CEmployee {
public:
virtual void Accept(IVisitor *v)=0;
virtual int getSalary(){
return 0;
}
};
class CProgrammer : public CEmployee{
public:
virtual void Accept(IVisitor *v){
v->Visit(this);
}
virtual int getSalary(){
return 100;
}
};
class CJuniorProgrammer : public CEmployee{
public:
virtual void Accept(IVisitor *v){
v->Visit(this);
}
virtual int getSalary(){
return 500;
}
};
class CVeteranProgrammer : public CEmployee{
public:
virtual void Accept(IVisitor *v){
v->Visit(this);
}
virtual int getSalary(){
return 1000;
}
};
class CManager : public CEmployee{
public:
virtual void Accept(IVisitor *v){
v->Visit(this);
}
virtual int getSalary(){
return 1000;
}
int getBonus(){
return 1000;
}
};
class CCEO : public CEmployee{
public:
virtual void Accept(IVisitor *v){
v->Visit(this);
}
int yearly_salary(){
return 120000;
}
};
class SalaryVisitor:public IVisitor{
public:
SalaryVisitor():sum_(0){}
virtual void Visit(CEmployee* p){
sum_ += p->getSalary();
}
virtual void Visit(CProgrammer* p){
sum_ += p->getSalary();
}
virtual void Visit(CManager* p){
sum_ += p->getSalary();
sum_ += p->getBonus();
}
virtual void Visit(CCEO* p){
sum_ += (p->yearly_salary() / 12);
}
public:
int GetTotalSalary(){
return sum_;
}
private:
int sum_;
};
//优点:CEmployee继承体系基本不会被冲击。如果SalaryVisitor算法有问题,只是更改SalaryVisitor即可。需要预先在CEmployee继承体系嵌入virtual void Accept(IVisitor *v)=0;,如果不让动旧代码,此模式失败。
如果增加新的雇员类型,就需要动IVisitor。同理,必将引起底层代码重编译。
int main() {
IVisitor* pv = new SalaryVisitor();
CEmployee* pe = new CCEO();
pe->Accept(pv);
return 0;
}
学习笔记:visitor模式和双分派
最新推荐文章于 2023-05-18 10:10:57 发布