您的位置:首页 > 编程语言 > C语言/C++

设计模式系列7-----C++实现访问者模式(Visitor Pattern)

2011-12-11 00:38 513 查看

什么是访问者模式?

      Definition:Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

      访问者模式最合适的使用情况是需要对一个家族的对象逐个访问,并根据具体的对象做出不同的操作,而且不希望改变原来的对象。当然在设计的时候需要让家族成员定义一个支持访问者模式的接口,即accept函数。以后需要添加新功能的时候只要增加相应的具体访问者类。

      当然访问者模式也有缺点,比如家族类里面新加了成员,每个具体访问者类也需要相应改变;类的状态对访问者完全透明,违背数据隐藏原则。等等

      访问者模式有用到双分配(double-dispatch)技术,由于Client使用的是抽象类Element和Visitor,无法达到对具体的Element调用相应的visit函数,需要在Element类的函数accept中转发visitor.visit(this),此时this是一个具体的类,能够调用到正确的函数。

 

类图结构:



Example:

      例子模式对班级活动收费,但是男生收费是女生费用的2倍。在不能向Student中添加函数的情况下,可以使用访问者模式。

people.h代码如下:

#ifndef __PEOPLE_H__
#define __PEOPLE_H__

#include <string>

class IVisitor;

class People
{
public:
People(std::string strName, int nMoney) : m_strName(strName), m_nMoney(nMoney) {}

void pay(int nMoneyToPay);

virtual void accept(IVisitor* pVisitor) = 0;

const std::string& getName() const;

private:
int m_nMoney;
std::string m_strName;
};

class Man : public People
{
public:
Man(std::string strName, int nMoney) : People(strName, nMoney) {}

virtual void accept(IVisitor* pVisitor);
};

class Woman : public People
{
public:
Woman(std::string strName, int nMoney) : People(strName, nMoney) {}

virtual void accept(IVisitor* pVisitor);
};
#endif


 

people.cpp代码如下:

#include "people.h"
#include "visitor.h"
#include <iostream>

void People::pay( int nMoneyToPay )
{
m_nMoney -= nMoneyToPay;
}

const std::string& People::getName() const
{
return m_strName;
}

void Man::accept( IVisitor* pVisitor )
{
pVisitor->visit(this);
}

void Woman::accept( IVisitor* pVisitor )
{
pVisitor->visit(this);
}


 

visitor.h代码如下:

#ifndef __VISITOR_H__
#define __VISITOR_H__

class Man;
class Woman;

class IVisitor
{
public:
virtual void visit(Man* pMan) = 0;
virtual void visit(Woman* pWoman) = 0;
};

class ChargeMoneyVisitor : public IVisitor
{
public:
ChargeMoneyVisitor() : m_nSum(0) {}

virtual void visit(Man* pMan);

virtual void visit(Woman* pWoman);

int getSum() const;

private:
int m_nSum;
static const int PAY = 10;
};
#endif


 

visitor.cpp代码如下:

#include "visitor.h"
#include "people.h"
#include <iostream>

void ChargeMoneyVisitor::visit( Man* pMan )
{
int nMoneyToCharge = 2*PAY;
pMan->pay(nMoneyToCharge);
m_nSum += nMoneyToCharge;
std::cout << pMan->getName() << " is charged " << nMoneyToCharge << " RMB\n";
}

void ChargeMoneyVisitor::visit( Woman* pWoman )
{
int nMoneyToCharge = PAY;
pWoman->pay(nMoneyToCharge);
m_nSum += nMoneyToCharge;
std::cout << pWoman->getName() << " is charged " << nMoneyToCharge << " RMB\n";
}

int ChargeMoneyVisitor::getSum() const
{
return m_nSum;
}


 

main.cpp代码如下:

#include "visitor.h"
#include "people.h"
#include <vector>
#include <iostream>

int main()
{
std::vector<People*> students;
students.push_back(new Man("Bob", 100));
students.push_back(new Woman("Lily", 100));

ChargeMoneyVisitor chargeMoneyVisitor;

std::vector<People*>::const_iterator iter = students.begin();
for (; iter != students.end(); ++iter)
{
People* pPeople = *iter;
pPeople->accept(&chargeMoneyVisitor);
}

std::cout << "Total charge money: " << chargeMoneyVisitor.getSum() << " RMB\n";

iter = students.begin();
for (; iter != students.end(); ++iter)
{
delete *iter;
}

return 0;
}


 

运行结果如下:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: