本文最后更新于 2025年7月28日 晚上
访问者模式表示一个作用于其对象结构中的各元素的操作,它可以在不改变各元素类的前提下,定义作用于这些元素的新操作。
访问者模式是一种将数据操作和数据结构分离的设计模式
角色
- 抽象访问接口:定义了对每一个元素访问的行为,它的参数就是可以访问的元素,它的方法个数理论上讲与元素个数是一样的。访问者模式要求元素类的个数不能改变
- 具体访问者角色:它需要给出对每一个元素类访问时产生的具体行为
- 抽象节点角色:它定义了一个接受访问者的方法,其意义是指每一个元素都可以被访问者访问
- 具体节点角色:它提供接受访问的方法的具体实现,而这个具体实现,通常情况下使用访问者提供的访问该元素类的方法
- 结构对象角色:一个包含元素集合,并负责遍历元素并将访问请求传递出去的容器
优点
- 访问者模式使得易于增加新的操作,访问者使得增加依赖于复杂对象结构的构件的操作变得容易,仅需增加一个新的访问者,即可在一个对象结构上定义一个新的操作。相反,如果每个功能都分散在多个类之上,定义新的操作时,必须修改每一类
- 访问者集中相关的操作而分离无关的操作
缺点
- 增加新的具体访问者角色很困难
- 访问者可能需要暴露元素的内部状态以完成访问逻辑,违反了信息隐藏原则。
实现访问者模式
访问者模式的核心思想是 状态转移与状态信息分离 。
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); } } }
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) 接口,访问者可以实现对不同元素的多态分发(双分派),从而在不修改元素类的前提下扩展新功能。