1. 访问者模式概述
访问者模式是《Head First设计模式》中介绍的23种设计模式之一,属于行为型模式。它主要解决的是在不修改已有类结构的前提下,为类增加新的操作功能。这种模式在实际开发中特别适用于需要对一个复杂对象结构(如组合结构)进行多种不同操作的场景。
我第一次接触访问者模式是在开发一个编译器前端时,需要对抽象语法树(AST)进行多种分析操作(如类型检查、代码优化等)。当时面临的问题是:如果把这些操作都放在AST节点类里实现,会导致类不断膨胀且难以维护。访问者模式完美解决了这个问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 模式结构与核心思想
2.1 UML类图解析
访问者模式的典型UML类图包含以下几个关键角色:
- Visitor(访问者):声明了一组访问方法,每个方法对应一个具体元素类
- ConcreteVisitor(具体访问者):实现Visitor接口,定义对各类元素的具体操作
- Element(元素):定义一个accept方法,接收访问者对象
- ConcreteElement(具体元素):实现Element接口,在accept方法中调用访问者的对应方法
- ObjectStructure(对象结构):包含元素集合,可以枚举元素并让访问者访问它们
2.2 双重分派机制
访问者模式的核心在于"双重分派"(Double Dispatch)机制。在C++中,这通过以下方式实现:
- 元素调用accept方法时,将自身类型(this指针)传递给访问者
- 访问者根据元素类型调用对应的visit方法
这种机制使得运行时能够根据元素和访问者的具体类型动态决定调用哪个方法,实现了操作与元素结构的解耦。
3. C++实现详解
3.1 基础实现框架
下面是一个最基本的访问者模式C++实现框架:
cpp复制// 前向声明
class ConcreteElementA;
class ConcreteElementB;
// 访问者接口
class Visitor {
public:
virtual ~Visitor() = default;
virtual void visit(ConcreteElementA* element) = 0;
virtual void visit(ConcreteElementB* element) = 0;
};
// 元素接口
class Element {
public:
virtual ~Element() = default;
virtual void accept(Visitor* visitor) = 0;
};
// 具体元素A
class ConcreteElementA : public Element {
public:
void accept(Visitor* visitor) override {
visitor->visit(this);
}
std::string opera
