访问者模式是一种行为型设计模式,它可以在不改变现有对象结构的前提下,定义对这些对象的新操作。
下面是一个使用 C++ 实现访问者模式的示例代码:
#include <iostream>
#include <vector>
// 前向声明
class ConcreteElementA;
class ConcreteElementB;
// 抽象访问者:定义了对各种具体元素进行访问的接口
class Visitor {
public:
virtual ~Visitor() {}
virtual void VisitConcreteElementA(ConcreteElementA* concrete_element_a) = 0;
virtual void VisitConcreteElementB(ConcreteElementB* concrete_element_b) = 0;
};
// 具体访问者:实现了抽象访问者定义的接口,对各种具体元素进行访问
class ConcreteVisitor1 : public Visitor {
public:
virtual void VisitConcreteElementA(ConcreteElementA* concrete_element_a) override {
std::cout << "Concrete Visitor 1: visit Concrete Element A" << std::endl;
}
virtual void VisitConcreteElementB(ConcreteElementB* concrete_element_b) override {
std::cout << "Concrete Visitor 1: visit Concrete Element B" << std::endl;
}
};
class ConcreteVisitor2 : public Visitor {
public:
virtual void VisitConcreteElementA(ConcreteElementA* concrete_element_a) override {
std::cout << "Concrete Visitor 2: visit Concrete Element A" << std::endl;
}
virtual void VisitConcreteElementB(ConcreteElementB* concrete_element_b) override {
std::cout << "Concrete Visitor 2: visit Concrete Element B" << std::endl;
}
};
// 抽象元素:定义了一个 Accept 操作,接受一个访问者对象作为参数
class Element {
public:
virtual ~Element() {}
virtual void Accept(Visitor* visitor) = 0;
};
// 具体元素:实现了抽象元素定义的接口,实现了 Accept 操作
class ConcreteElementA : public Element {
public:
virtual void Accept(Visitor* visitor) override {
visitor->VisitConcreteElementA(this);
}
};
class ConcreteElementB : public Element {
public:
virtual void Accept(Visitor* visitor) override {
visitor->VisitConcreteElementB(this);
}
};
// 对象结构:包含了一组具体元素对象,可以被访问者访问
class ObjectStructure {
public:
void AddElement(Element* element) {
elements_.push_back(element);
}
void RemoveElement(Element* element) {
// 省略删除元素的代码
}
void Accept(Visitor* visitor) {
for (auto element : elements_) {
element->Accept(visitor);
}
}
private:
std::vector<Element*> elements_;
};
int main() {
// 创建对象结构和访问者对象
ObjectStructure object_structure;
ConcreteVisitor1 concrete_visitor1;
ConcreteVisitor2 concrete_visitor2;
// 向对象结构中添加具体元素对象
object_structure.AddElement(new ConcreteElementA);
object_structure.AddElement(new ConcreteElementB);
// 让访问者1访问对象结构中的元素
object_structure.Accept(&concrete_visitor1);
// 输出 "Concrete Visitor 1: visit Concrete Element A" 和 "Concrete Visitor 1: visit Concrete Element B"
// 让访问者2访问对象结构中的元素
object_structure.Accept(&concrete_visitor2);
// 输出 "Concrete Visitor 2: visit Concrete Element A" 和 "Concrete Visitor 2: visit Concrete Element B"
return 0;
}
在上面的代码中,我们首先定义了一个抽象访问者 Visitor,它定义了对各种具体元素进行访问的接口。接着,我们创建了两个具体访问者 ConcreteVisitor1 和 ConcreteVisitor2,它们实现了 Visitor 中定义的接口,对各种具体元素进行访问。
在 Element 中,我们定义了一个 Accept() 操作,接受一个访问者对象作为参数。具体元素 ConcreteElementA 和 ConcreteElementB 实现了 Element 中定义的接口,实现了 Accept() 操作。
在 ObjectStructure 中,我们包含了一组具体元素对象,可以被访问者访问。最后,在 main() 函数中,我们创建了对象结构和访问者对象,向对象结构中添加具体元素对象,让访问者访问对象结构中的元素,并输出访问的结果。
访问者模式的优点在于它可以在不改变现有对象结构的前提下,定义对这些对象的新操作。通过将访问者的操作分离出来,我们可以在不同的元素上实现不同的操作,从而增加了代码的灵活性和可扩展性。但是,访问者模式也可能导致代码的复杂度增加,因为我们需要定义访问者接口、具体访问者和抽象元素,从而增加了代码的数量。