访问者模式是一种将算法与对象结构分离的软件设计模式。它可以让你在不修改对象结构的情况下,对对象结构中的元素进行不同的操作。访问者模式的优点是符合单一职责原则,优秀的扩展性和灵活性。缺点是具体元素对访问者公布细节,违反了迪米特原则,而且如果元素类经常变化,会导致访问者类需要频繁修改。

访问者模式适合在以下场景下使用:
– 对象结构比较稳定,但经常需要在此对象结构上定义新的操作。
– 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。
– 对象结构中的元素类型很少变化,但每个元素都有很多种变化的可能性,并且每一种变化都影响到元素的行为。

一个访问者模式的例子。

这个例子中,有一个计算机组件的接口(ComputerPart),它有一个accept方法用来接受访问者对象(ComputerPartVisitor)。

然后有三个实现了这个接口的类:键盘(Keyboard),鼠标(Mouse)和显示器(Monitor)。

每个类都实现了accept方法,调用访问者对象的visit方法,并传递自身作为参数。

访问者对象是一个接口,它有三个visit方法,分别对应三种不同的计算机组件。然后有两个实现了这个接口的类:计算机显示访问者(ComputerDisplayVisitor)和计算机修理访问者(ComputerRepairVisitor)。

每个类都实现了三个visit方法,分别对不同的计算机组件执行不同的操作。

最后,有一个计算机类(Computer),它包含了三种计算机组件,并且也实现了accept方法,调用每个组件的accept方法,并传递自身作为参数。下面是部分代码:

// 计算机组件接口public interface ComputerPart {public void accept(ComputerPartVisitor computerPartVisitor);}// 键盘类public class Keyboard implements ComputerPart {@Overridepublic void accept(ComputerPartVisitor computerPartVisitor) {computerPartVisitor.visit(this);}}// 鼠标类public class Mouse implements ComputerPart {@Overridepublic void accept(ComputerPartVisitor computerPartVisitor) {computerPartVisitor.visit(this);}}// 显示器类public class Monitor implements ComputerPart {@Overridepublic void accept(ComputerPartVisitor computerPartVisitor) {computerPartVisitor.visit(this);}}// 访问者接口public interface ComputerPartVisitor {public void visit(Keyboard keyboard);public void visit(Mouse mouse);public void visit(Monitor monitor);}// 计算机显示访问者类public class ComputerDisplayVisitor implements ComputerPartVisitor {@Overridepublic void visit(Keyboard keyboard) {System.out.println("Displaying Keyboard.");}@Overridepublic void visit(Mouse mouse) {System.out.println("Displaying Mouse.");}@Overridepublic void visit(Monitor monitor) {System.out.println("Displaying Monitor.");}}// 计算机修理访问者类public class ComputerRepairVisitor implements ComputerPartVisitor {@Overridepublic void visit(Keyboard keyboard) {System.out.println("Repairing Keyboard.");}@Overridepublic void visit(Mouse mouse) {System.out.println("Repairing Mouse.");}@Overridepublic void visit(Monitor monitor) {System.out.println("Repairing Monitor.");}}// 计算机类public class Computer implements ComputerPart {private final List components;// 构造函数初始化键盘、鼠标和显示器// 实现accept方法// 调用每个组件的accept方法,并传递自身作为参数}

这段代码的目的是演示访问者模式的用法,它定义了一个计算机组件的接口,和三个实现了这个接口的类,分别代表键盘、鼠标和显示器。这些类都有一个accept方法,用来接受一个访问者对象,并调用它的visit方法。访问者对象是一个接口,它有三个visit方法,分别对应三种不同的计算机组件。这个接口有两个实现类,分别是计算机显示访问者和计算机修理访问者。这两个类都实现了三个visit方法,分别对不同的计算机组件执行不同的操作。例如,计算机显示访问者会打印出每个组件的名称,而计算机修理访问者会打印出每个组件正在被修理。最后,有一个计算机类,它包含了三种计算机组件,并且也实现了accept方法。当调用这个方法时,它会遍历所有的组件,并调用它们的accept方法,并传递自身作为参数。这样就可以根据不同的访问者对象,在不修改原有类结构和行为的情况下,对每个组件执行不同的操作。

假设我们创建了一个计算机对象,然后分别用计算机显示访问者和计算机修理访问者来访问它,那么运行结果可能是这样的:

// 创建一个计算机对象Computer computer = new Computer();// 创建一个计算机显示访问者对象ComputerDisplayVisitor displayVisitor = new ComputerDisplayVisitor();// 调用计算机的accept方法,并传递显示访问者对象computer.accept(displayVisitor);// 输出结果:Displaying Keyboard.Displaying Mouse.Displaying Monitor.// 创建一个计算机修理访问者对象ComputerRepairVisitor repairVisitor = new ComputerRepairVisitor();// 调用计算机的accept方法,并传递修理访问者对象computer.accept(repairVisitor);// 输出结果:Repairing Keyboard.Repairing Mouse.Repairing Monitor.