1. 意图
表示一个作用于某对象结构中的各元素的操作。
使你可以在不改变各元素的类的前提下定义于作用于这些元素的新操作。
2. 五种角色
抽象访问者(Visitor)、具体访问者(Concrete Visitor)、抽象元素(Element)、
具体元素(Concrete Element)、对象结构(ObjectStructure)
3. 优点
3.1 易于增加新的操作
3.2 集中相关的操作,而分离无关的操作
3.3 可以访问不具有相同父类的对象
4. 缺点
4.1 增加新的具体元素很困难
4.2 可能累积状态
4.3 可能破坏元素的封装性
5. 相关模式
5.1 访问者可以对一个由Composite模式定义的对象结构进行操作。
5.2 访问者可以用于解释器。
6. 代码示意
#pragma once
#include <vector>
#include <string>
#include <iostream>
using namespace std;
class ElementA;
class ElementB;
class Visitor
{
public:
virtual void VisitElementA(ElementA* pElementA) = 0;
virtual void VisitElementB(ElementB* pElementB) = 0;
};
class ConcreteVisitor1 : public Visitor
{
public:
virtual void VisitElementA(ElementA* pElementA);
virtual void VisitElementB(ElementB* pElementB);
};
class ConcreteVisitor2 : public Visitor
{
public:
virtual void VisitElementA(ElementA* pElementA);
virtual void VisitElementB(ElementB* pElementB);
};
class Element
{
public:
virtual void Accept(Visitor* pVisitor) = 0;
};
class ElementA : public Element
{
public:
virtual void Accept(Visitor* pVisitor) {
pVisitor->VisitElementA(this);
}
void OperationA(const string& name) {
cout << "ElementA 来自 " << name << " 的访问" << endl;
}
};
class ElementB : public Element
{
public:
virtual void Accept(Visitor* pVisitor) {
pVisitor->VisitElementB(this);
}
void OperationB(const string& name) {
cout << "ElementB 来自 " << name << " 的访问" << endl;
}
};
class ObjectStructure
{
vector<Element*> m_elememts;
public:
ObjectStructure() {
m_elememts.emplace_back(new ElementA());
m_elememts.emplace_back(new ElementB());
}
~ObjectStructure() {
auto it = m_elememts.begin();
while (it != m_elememts.end()) {
delete* it;
++it;
}
}
void Visit(Visitor* pVisitor) {
auto it = m_elememts.begin();
while (it != m_elememts.end()) {
(*it)->Accept(pVisitor);
++it;
}
}
};
Visitor.cpp:
#include "Visitor.h"
void ConcreteVisitor1::VisitElementA(ElementA* pElementA) {
pElementA->OperationA("Visitor1");
}
void ConcreteVisitor1::VisitElementB(ElementB* pElementB) {
pElementB->OperationB("Visitor1");
}
void ConcreteVisitor2::VisitElementA(ElementA* pElementA) {
pElementA->OperationA("Visitor2");
}
void ConcreteVisitor2::VisitElementB(ElementB* pElementB) {
pElementB->OperationB("Visitor2");
}
#include "Visitor.h"
int main() {
ObjectStructure* pObjStructure = new ObjectStructure();
Visitor* pVisitor = new ConcreteVisitor1();
pObjStructure->Visit(pVisitor);
delete pVisitor;
pVisitor = new ConcreteVisitor2();
pObjStructure->Visit(pVisitor);
delete pVisitor;
delete pObjStructure;
return 0;
}
运行结果:
6.1 ObjectStructure提供访问所有元素的接口
6.2 增加新的ConcreteVisitor3就可以定义一个新的操作(3.1)
6.3 抽象Visitor里的接口集中了相关的操作(3.2)
6.4 增加新的ElementC,所有Visitor类和ObjectStructure都要修改(4.1)