设计模式系列7-----C++实现访问者模式(Visitor Pattern)
什么是访问者模式?
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; }
运行结果如下:
posted on 2011-12-11 00:38 GraphicsMe 阅读(3247) 评论(0) 编辑 收藏 举报