
访问者模式定义
访问者模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,在不改变数据结构的前提下定义一些新的操作。
访问者模式将对数据的操作,与数据结构进行分离,是行为类模式中最复杂的一种模式。
访问者模式作用
访问者模式作用:简单来说访问者模式主要的作用就是将“数据结构”和“数据操作”进行分离,解决这两者之间耦合性的问题。
访问者模式角色
访问者模式实现的关键:是如何将作用于元素的操作分离出来封装成独立的类。
访问者模式的基本结构,包含以下主要角色,如下图所示:

1. Vistor(抽象访问者)
定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作 visit() ,该操作中的参数类型标识了被访问的具体元素,就好像是王者荣耀里面不同的玩家。
2. ConcreteVisitor(具体访问者)
每个具体访问者都实现了Vistor中定义的操作,就好比是具体某一个玩家。
3. Element(抽象元素)
声明一个包含接受操作 accept() 的接口,被接受的访问者对象作为 accept() 方法的参数,可以类比成王者里面英雄的模板。
4.ConcreteElement(具体元素)
实现了Element中的accept()方法,调用Vistor的访问方法以便完成对一个元素的操作,可以表示为具体某一个英雄,好比是庄周和甄姬。
5. ObjectStructure(对象结构)
可以是组合模式,也可以是集合,是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法,通常由 List、Set、Map 等聚合类实现。
访问者模式类图如下:

访问者模式案例
访问者模式的KPI考核的代码示例,具体会包含如下的角色:
1.抽象元素:Employee
public abstract class Employee {
public String name;
public int kpi; //员工KPI
public Employee(String name) {
this.name = name;
kpi = new Random().nextInt(10);
}
//接收访问者的访问
public abstract void accept(Visitor visitor);
}
2.抽象访问者:Visitor
public interface Visitor {
void visit(Engineer engineer);
void visit(Manager manager);
}
3.具体元素:Engineer
public class Engineer extends Employee {
public Engineer(String name) {
super(name);
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
//考核指标是每年的代码量
public int getCodeLines() {
return new Random().nextInt(10 * 10000);
}
}
4.具体元素:Manager
public class Manager extends Employee {
public Manager(String name) {
super(name);
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
//考核的是每年新产品研发数量
public int getProducts() {
return new Random().nextInt(10);
}
}
5.具体访问者:CEOVisitor
public class CEOVisitor implements Visitor {
@Override
public void visit(Engineer engineer) {
System.out.println("工程师" engineer.name ",KIP:" engineer.kpi);
}
@Override
public void visit(Manager manager) {
System.out.println("经理:" manager.name ",KPI:" manager.kpi ",产品数量:" manager.getProducts());
}
}
6.具体访问者:CTOVisitor
public class CTOVisitor implements Visitor {
@Override
public void visit(Engineer engineer) {
System.out.println("工程师" engineer.name ",代码行数:" engineer.getCodeLines());
}
@Override
public void visit(Manager manager) {
System.out.println("经理:" manager.name ",产品数量:" manager.getProducts());
}
}
6.测试
public class Test {
public static void main(String[] args) {
BusinessReport report = new BusinessReport();
System.out.println("==========CEO看报表===============");
report.showReport(new CEOVisitor());
System.out.println("==========CTO看报表===============");
report.showReport(new CTOVisitor());
}
}
访问者模式应用
- 对象结构比较稳定,但经常需要在此对象结构上定义新的操作。
- 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。
mikechen睿哥
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。