1. 访问者模式:土地面积计算的优雅解法
在软件开发中,我们经常遇到需要对一组对象执行不同操作的情况。以土地面积计算为例,圆形和长方形土地的面积计算公式完全不同。传统做法是在每个土地类中直接实现面积计算方法,但这种硬编码方式存在明显缺陷:当需要新增计算维度(如周长、税费)时,必须修改所有土地类的源代码。
访问者模式(Visitor Pattern)完美解决了这个问题。它属于行为型设计模式,核心思想是将数据结构与数据操作分离。就像为不同类型的土地配备专属核算员,核算员带着计算规则"拜访"每块土地,而土地本身只需提供必要参数。
1.1 模式优势与实际应用
访问者模式特别适用于以下场景:
- 数据结构(如土地类型)相对稳定
- 操作(如计算逻辑)频繁变化或扩展
- 需要对同一组对象执行多种不相关的操作
实际应用案例包括:
- 电商促销系统:不同商品类型(图书、家电)适用不同的优惠计算规则
- 报表生成系统:同一数据源需要生成多种统计报表
- 编译器设计:语法树节点固定,但需要支持多种分析操作(如类型检查、代码优化)
提示:当发现自己在不断修改类来添加新功能时,就该考虑访问者模式了。它让新增操作变得简单,只需添加新的访问者类,无需修改现有类结构。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 访问者模式核心架构解析
2.1 五大核心角色
访问者模式的实现需要五个关键组件协同工作:
- 抽象访问者(Visitor)
定义访问各类具体元素的接口,通常为每个具体元素类声明一个visit方法。例如:
cpp复制class Visitor {
public:
virtual void visit(Circle&) = 0;
virtual void visit(Rectangle&) = 0;
};
- 具体访问者(ConcreteVisitor)
实现抽象访问者接口,包含具体的操作逻辑。如面积计算器:
cpp复制class AreaCalculator : public Visitor {
void visit(Circle& c) override {
// 实现圆形面积计算
}
// 其他visit实现...
};
- 抽象元素(Element)
定义accept接口,用于接收访问者:
cpp复制class Shape {
public:
virtual void accept(Visitor&) = 0;
};
- 具体元素(ConcreteElement)
实现accept方法,通常形式为:
cpp复制void Circle::accept(Visitor& v) {
v.visit(*this); // 调用访问者对应的visit方法
}
- 对象结构(ObjectStructure)
管理元素集合,提供遍历接口:
cpp复制class Drawing {
std::vector<Shape*> shapes;
public:
void accept(V
