访问者模式

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

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

 

一个访问者模式的例子。

这个例子中,有一个计算机组件的接口(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 {

@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}

// 鼠标类
public class Mouse implements ComputerPart {

@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}

// 显示器类
public class Monitor implements ComputerPart {

@Override
public 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 {

@Override
public void visit(Keyboard keyboard) {
System.out.println("Displaying Keyboard.");
}

@Override
public void visit(Mouse mouse) {
System.out.println("Displaying Mouse.");
}

@Override
public void visit(Monitor monitor) {
System.out.println("Displaying Monitor.");
}
}

// 计算机修理访问者类
public class ComputerRepairVisitor implements ComputerPartVisitor {

@Override
public void visit(Keyboard keyboard) {
System.out.println("Repairing Keyboard.");
}

@Override
public void visit(Mouse mouse) {
System.out.println("Repairing Mouse.");
}

@Override
public void visit(Monitor monitor) {
System.out.println("Repairing Monitor.");
}
}

// 计算机类

public class Computer implements ComputerPart {

private final List<ComputerComponent> 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.

 

 
posted @ 2023-03-03 14:04  一摩尔时光  阅读(96)  评论(0编辑  收藏  举报