java23种设计模式-访问者模式
访问者模式(Visitor Pattern)学习笔记
编程相关书籍分享:https://blog.csdn.net/weixin_47763579/article/details/145855793
一、模式定义
🌐 行为型设计模式,通过将算法与对象结构分离,在不修改现有对象结构的前提下定义新操作。符合开闭原则(对扩展开放,对修改关闭)。
二、类图(Mermaid表示)
三、核心组成
-
Visitor(访问者接口)
- 声明
visit方法集合(参数类型对应具体元素类型)
- 声明
-
ConcreteVisitor(具体访问者)
- 实现
visit方法,定义对具体元素的操作
- 实现
-
Element(元素接口)
- 定义
accept方法接收访问者对象
- 定义
-
ConcreteElement(具体元素)
- 实现
accept方法,调用访问者的visit方法
- 实现
-
ObjectStructure(对象结构)
- 维护元素集合,提供遍历元素的接口
四、Java实现示例
// 元素接口
interface Element {
void accept(Visitor visitor);
}
// 具体元素A
class ConcreteElementA implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operationA() {
return "ElementA Operation";
}
}
// 具体元素B
class ConcreteElementB implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operationB() {
return "ElementB Operation";
}
}
// 访问者接口
interface Visitor {
void visit(ConcreteElementA element);
void visit(ConcreteElementB element);
}
// 具体访问者1
class ConcreteVisitor1 implements Visitor {
public void visit(ConcreteElementA element) {
System.out.println("Visitor1 processing: " + element.operationA());
}
public void visit(ConcreteElementB element) {
System.out.println("Visitor1 processing: " + element.operationB());
}
}
// 对象结构
class ObjectStructure {
private List<Element> elements = new ArrayList<>();
public void addElement(Element element) {
elements.add(element);
}
public void accept(Visitor visitor) {
for (Element element : elements) {
element.accept(visitor);
}
}
}
// 使用示例
public class Client {
public static void main(String[] args) {
ObjectStructure structure = new ObjectStructure();
structure.addElement(new ConcreteElementA());
structure.addElement(new ConcreteElementB());
Visitor visitor1 = new ConcreteVisitor1();
structure.accept(visitor1);
}
}
五、双分派机制
🚀 两次动态绑定:
- 元素通过
accept方法选择接收访问者 - 访问者通过
visit方法选择处理具体元素类型
六、适用场景
✅ 需要对复杂对象结构(如组合结构)添加新操作
✅ 数据结构稳定但需要频繁添加新算法
✅ 需要分离无关行为避免污染类
✅ 需要运行时选择不同处理逻辑
七、优缺点分析
✔️ 优点:
- 符合单一职责原则
- 优秀的扩展性(新增访问者不影响现有系统)
- 集中相关行为
❌ 缺点:
- 增加新元素类型困难(需要修改所有访问者)
- 破坏元素封装性(需要暴露内部状态)
- 不适用于元素结构频繁变化的场景
八、实际应用
- 编译器:语法树分析(类型检查、代码优化)
- 文件系统处理:不同格式文件的处理
- XML解析:DOM树遍历处理
- ASM字节码框架:ClassVisitor体系
- JDK示例:
java.nio.file.FileVisitor
九、相关模式对比
| 模式 | 关注点 |
|---|---|
| 访问者 | 在对象结构上执行操作 |
| 迭代器 | 遍历集合元素 |
| 组合模式 | 处理树形结构 |
| 装饰器 | 动态添加职责 |
建议结合具体业务场景(如电商订单处理、文档转换工具)进行实践练习,加深对双分派机制的理解。
浙公网安备 33010602011771号