概述
访问者模式(Visitor Pattern)
是一种行为型设计模式,它允许你在不修改对象结构的情况下定义作用于这些对象的新操作。访问者模式通过将操作封装到访问者对象中,使得可以在不改变元素类的前提下,增加新的操作。该模式适用于数据结构相对稳定,而操作易于变化的系统。
使用场景
- 当你需要对一个对象结构中的对象进行很多不同且不相关的操作,而你不希望这些操作“污染”对象的类时。
- 当对象结构是稳定的,但经常需要在此对象结构上定义新的操作时。
- 需要对一个对象结构中的不同类型对象执行不同操作,但不希望因为增加新操作而修改这些对象的类时。
结构
访问者模式包含以下几个部分:
- 访问者接口(Visitor):定义了一个访问者可以访问对象结构中不同类型元素的方法。
- 具体访问者(ConcreteVisitor):实现访问者接口,定义对不同类型元素的具体操作。
- 元素接口(Element):定义一个接受访问者的方法(通常是
accept
方法),该方法通常会调用访问者的相应方法。 - 具体元素(ConcreteElement):实现元素接口,定义具体的
accept
方法。 - 对象结构(ObjectStructure):包含元素的集合,可以遍历这些元素并对它们进行访问操作。
代码实现
下面是一个 Java 实现访问者模式的例子,展示了如何通过访问者模式在不修改元素类的情况下增加新的操作。
示例代码:
import java.util.ArrayList;
import java.util.List;
// 访问者接口
interface Visitor {
void visit(ElementA element);
void visit(ElementB element);
}
// 具体访问者类
class ConcreteVisitor implements Visitor {
@Override
public void visit(ElementA element) {
System.out.println("Processing ElementA: " + element.getName());
}
@Override
public void visit(ElementB element) {
System.out.println("Processing ElementB: " + element.getValue());
}
}
// 元素接口
interface Element {
void accept(Visitor visitor);
}
// 具体元素类A
class ElementA implements Element {
private String name;
public ElementA(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// 具体元素类B
class ElementB implements Element {
private int value;
public ElementB(int value) {
this.value = value;
}
public int getValue() {
return value;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// 对象结构类
class ObjectStructure {
private List<Element> elements = new ArrayList<>();
public void addElement(Element element) {
elements.add(element);
}
public void accept(Visitor visitor) {
for (Element element : elements) {
element.accept(visitor);
}
}
}
// 客户端代码
public class VisitorPatternDemo {
public static void main(String[] args) {
ObjectStructure objectStructure = new ObjectStructure();
objectStructure.addElement(new ElementA("Element A1"));
objectStructure.addElement(new ElementA("Element A2"));
objectStructure.addElement(new ElementB(100));
objectStructure.addElement(new ElementB(200));
Visitor visitor = new ConcreteVisitor();
objectStructure.accept(visitor);
}
}