行为型-访问者模式
2026/1/15大约 2 分钟Java设计模式行为型模式访问者模式Java设计模式面向对象架构设计最佳实践代码优化
概述
访问者模式(Visitor Pattern)表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
适用场景
- 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作
- 需要对一个对象结构中的对象进行很多不同的并且不相关的操作
角色组成
- Visitor(抽象访问者):为每个ConcreteElement声明一个Visit操作
- ConcreteVisitor(具体访问者):实现每个Visit操作
- Element(抽象元素):定义一个Accept操作
- ConcreteElement(具体元素):实现Accept操作
- ObjectStructure(对象结构):能枚举它的元素
代码实现
1. 抽象元素
public interface ComputerPart {
void accept(ComputerPartVisitor visitor);
}2. 具体元素
public class Keyboard implements ComputerPart {
@Override
public void accept(ComputerPartVisitor visitor) {
visitor.visit(this);
}
}
public class Monitor implements ComputerPart {
@Override
public void accept(ComputerPartVisitor visitor) {
visitor.visit(this);
}
}
public class Mouse implements ComputerPart {
@Override
public void accept(ComputerPartVisitor visitor) {
visitor.visit(this);
}
}
public class Computer implements ComputerPart {
private ComputerPart[] parts;
public Computer() {
parts = new ComputerPart[]{new Keyboard(), new Monitor(), new Mouse()};
}
@Override
public void accept(ComputerPartVisitor visitor) {
for (ComputerPart part : parts) {
part.accept(visitor);
}
visitor.visit(this);
}
}3. 抽象访问者
public interface ComputerPartVisitor {
void visit(Keyboard keyboard);
void visit(Monitor monitor);
void visit(Mouse mouse);
void visit(Computer computer);
}4. 具体访问者
// 显示访问者
public class DisplayVisitor implements ComputerPartVisitor {
@Override
public void visit(Keyboard keyboard) {
System.out.println("显示键盘");
}
@Override
public void visit(Monitor monitor) {
System.out.println("显示显示器");
}
@Override
public void visit(Mouse mouse) {
System.out.println("显示鼠标");
}
@Override
public void visit(Computer computer) {
System.out.println("显示电脑");
}
}
// 价格访问者
public class PriceVisitor implements ComputerPartVisitor {
private double totalPrice = 0;
@Override
public void visit(Keyboard keyboard) {
totalPrice += 200;
}
@Override
public void visit(Monitor monitor) {
totalPrice += 1500;
}
@Override
public void visit(Mouse mouse) {
totalPrice += 100;
}
@Override
public void visit(Computer computer) {
System.out.println("电脑总价: " + totalPrice + " 元");
}
}5. 客户端
public class Client {
public static void main(String[] args) {
ComputerPart computer = new Computer();
System.out.println("=== 显示访问者 ===");
computer.accept(new DisplayVisitor());
System.out.println("\n=== 价格访问者 ===");
computer.accept(new PriceVisitor());
}
}# 输出
=== 显示访问者 ===
显示键盘
显示显示器
显示鼠标
显示电脑
=== 价格访问者 ===
电脑总价: 1800.0 元类图
双分派
访问者模式使用了双分派技术:
- 第一次分派:调用
element.accept(visitor) - 第二次分派:在 accept 中调用
visitor.visit(this)
优缺点
优点:
- 符合单一职责原则
- 优秀的扩展性
- 灵活性
缺点:
- 具体元素对访问者公布细节,违反迪米特原则
- 具体元素变更困难
- 违反依赖倒置原则
