访问者模式

本文最后更新于 2025年7月28日 晚上

访问者模式表示一个作用于其对象结构中的各元素的操作,它可以在不改变各元素类的前提下,定义作用于这些元素的新操作。

访问者模式是一种将数据操作和数据结构分离的设计模式

角色

  1. 抽象访问接口:定义了对每一个元素访问的行为,它的参数就是可以访问的元素,它的方法个数理论上讲与元素个数是一样的。访问者模式要求元素类的个数不能改变
  2. 具体访问者角色:它需要给出对每一个元素类访问时产生的具体行为
  3. 抽象节点角色:它定义了一个接受访问者的方法,其意义是指每一个元素都可以被访问者访问
  4. 具体节点角色:它提供接受访问的方法的具体实现,而这个具体实现,通常情况下使用访问者提供的访问该元素类的方法
  5. 结构对象角色:一个包含元素集合,并负责遍历元素并将访问请求传递出去的容器

优点

  1. 访问者模式使得易于增加新的操作,访问者使得增加依赖于复杂对象结构的构件的操作变得容易,仅需增加一个新的访问者,即可在一个对象结构上定义一个新的操作。相反,如果每个功能都分散在多个类之上,定义新的操作时,必须修改每一类
  2. 访问者集中相关的操作而分离无关的操作

缺点

  1. 增加新的具体访问者角色很困难
  2. 访问者可能需要暴露元素的内部状态以完成访问逻辑,违反了信息隐藏原则。

实现访问者模式

访问者模式的核心思想是 状态转移与状态信息分离 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
public interface Visitor {
void visit(Engineer engineer);
void visit(Manager manager);
}

// 定义员工抽象类
public abstract class Employee{
public String name ;
public int kpi ;

public Employee(String name){
this.name = name ;
this.kpi = new Random().nextInt(10);
}

public abstract void accept(Visitor visitor);
}

// 实现类
public class Engineer extends Employee{
public Engineer (String name){
super(name);
}

@Override
public void accept(Visitor visitor){
visitor.visit(this);
}
}

public class Manager extends Employee{
public Manager(String name){
super(name);
}

@Override
public void accept(Visitor visitor){
visitor.visit(this);
}

}

//
public class BusinessReport {
private List<Employee>employees = new ArrayList<>();

public BusinessReport(){
employees.add(new Manager("经理-A"));
employees.add(new Manager("经理-B"));
employees.add(new Engineer("工程师-A"));
employees.add(new Engineer("工程师-B"));
}

public void showReport(Visitor visitor){
for(Employee employee : employees){
employee.accept(visitor);
}
}
}

// Visitor的实现类
public class CEOVisitor implements Visitor{
@Override
public void visit(Engineer engineer){
System.out.println("工程师:" + engineer.name + "KPI:" + engineer.kpi);
}
@Override
public void visit(Manager manager){
System.out.println("经理:" + manager.name +"KPI" + manager.kpi);
}
}

// 调用
public class Client{
public static void main(String[] args){
BusinessReport report = new BusinessReport();
System.out.println("看报表");
report.showReport(new CEOVisitor());
}
}

总结

访问者模式是一种 将操作与数据结构分离 的行为型设计模式,适用于对象结构稳定但操作频繁变化的场景。通过为每一个元素提供一个 accept(Visitor) 接口,访问者可以实现对不同元素的多态分发(双分派),从而在不修改元素类的前提下扩展新功能。


访问者模式
http://gadoid.io/2025/07/28/访问者模式/
作者
Codfish
发布于
2025年7月28日
许可协议