访问者模式
简介
参考链接
解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。
UML类图
代码示例
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class Visitor;
// 被访问元素
class Element
{
protected:
std::string m_strName;
public:
Element(std::string str) { m_strName = str; }
virtual void Accept(Visitor *visitor) = 0;
std::string getName() { return m_strName; }
};
class ConcreteElementA : public Element
{
public:
ConcreteElementA(std::string str) : Element(str) {}
void Accept(Visitor *visitor);
};
class ConcreteElementB : public Element
{
public:
ConcreteElementB(std::string str) : Element(str) {}
void Accept(Visitor *visitor);
};
// 访问者
class Visitor
{
public:
virtual void VisitConcreteElementA(ConcreteElementA *p) = 0;
virtual void VisitConcreteElementB(ConcreteElementB *p) = 0;
};
class ConcreteVisitorA : public Visitor
{
public:
void VisitConcreteElementA(ConcreteElementA *p)
{
std::cout << "ConcreteVisitorA 访问了" << p->getName() << std::endl;
}
void VisitConcreteElementB(ConcreteElementB *p)
{
std::cout << "ConcreteVisitorA 访问了" << p->getName() << std::endl;
}
};
class ConcreteVisitorB : public Visitor
{
public:
void VisitConcreteElementA(ConcreteElementA *p)
{
std::cout << "ConcreteVisitorB 访问了" << p->getName() << std::endl;
}
void VisitConcreteElementB(ConcreteElementB *p)
{
std::cout << "ConcreteVisitorB 访问了" << p->getName() << std::endl;
}
};
void ConcreteElementA::Accept(Visitor *visitor)
{
visitor->VisitConcreteElementA(this);
}
void ConcreteElementB::Accept(Visitor *visitor)
{
visitor->VisitConcreteElementB(this);
}
// 聚集类
class ObjectStructure
{
private:
std::vector<Element *> m_vec;
public:
~ObjectStructure() {
for (auto it = m_vec.begin(); it != m_vec.end(); it++) {
delete *it;
}
m_vec.clear();
}
void add(Element *p) { m_vec.push_back(p); }
void accept(Visitor *visitor) {
for (auto it = m_vec.cbegin(); it != m_vec.cend(); it++) {
(*it)->Accept(visitor);
}
}
};
int main()
{
// 访问者模式
ObjectStructure *p = new ObjectStructure();
p->add(new ConcreteElementA("AElement"));
p->add(new ConcreteElementB("B"));
ConcreteVisitorA *pVisitorA = new ConcreteVisitorA();
ConcreteVisitorB *pVisitorB = new ConcreteVisitorB();
p->accept(pVisitorA);
p->accept(pVisitorB);
delete pVisitorA;
delete pVisitorB;
delete p;
return 0;
}