1. 基本概念

访问者模式(Visitor Pattern)是一种行为型设计模式,可以在不改变对象结构的前提下,对对象中的元素进行新的操作。

2. 基本结构

访问者模式包括以下几个基本角色:

  • 抽象访问者(Visitor): 声明了访问者可以访问哪些元素,以及如何访问它们的方法visit
  • 具体访问者(ConcreteVisitor): 实现了抽象访问者定义的方法,不同的元素类型可能有不同的访问行为。医生、管理员、游客都属于具体的访问者,它们的访问行为不同。
  • 抽象元素(Element): 定义了一个accept方法,用于接受访问者的访问。
  • 具体元素(ConcreteElement): 实现了accept方法,是访问者访问的目标。
  • 对象结构(Object Structure): 包含元素的集合,可以是一个列表、一个集合或者其他数据结构。负责遍历元素,并调用元素的接受方法。

image-20240519164649386

3. 简易实现

  1. 定义抽象访问者: 声明那些元素可以访问
1
2
3
4
5
// 抽象访问者
interface Visitor {
void visit(ConcreteElementA element);
void visit(ConcreteElementB element);
}
  1. 实现具体访问者:实现具体的访问逻辑
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
// 具体访问者A
class ConcreteVisitorA implements Visitor {
@Override
public void visit(ConcreteElementA element) {
System.out.println("ConcreteVisitorA Visit ConcreteElementA");
}

@Override
public void visit(ConcreteElementB element) {
System.out.println("ConcreteVisitorA Visit ConcreteElementB");
}
}

// 具体访问者B
class ConcreteVisitorB implements Visitor {
@Override
public void visit(ConcreteElementA element) {
System.out.println("ConcreteVisitorB Visit ConcreteElementA");
}

@Override
public void visit(ConcreteElementB element) {
System.out.println("ConcreteVisitorB Visit ConcreteElementB");
}
}
  1. 定义元素接口:声明接收访问者的方法。
1
2
3
4
// 抽象元素
interface Element {
void accept(Visitor visitor);
}
  1. 实现具体元素:实现接受访问者的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 具体元素A
class ConcreteElementA implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}

// 具体元素B
class ConcreteElementB implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
  1. 创建对象结构:提供一个接口让访问者访问它的元素。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 对象结构
class ObjectStructure {
private List<Element> elements = new ArrayList<>();

public void attach(Element element) {
elements.add(element);
}

public void detach(Element element) {
elements.remove(element);
}

public void accept(Visitor visitor) {
for (Element element : elements) {
element.accept(visitor);
}
}
}
  1. 客户端调用
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Main {
public static void main(String[] args) {
ObjectStructure objectStructure = new ObjectStructure();
objectStructure.attach(new ConcreteElementA());
objectStructure.attach(new ConcreteElementB());

Visitor visitorA = new ConcreteVisitorA();
Visitor visitorB = new ConcreteVisitorB();

objectStructure.accept(visitorA);
objectStructure.accept(visitorB);
}
}

4. 使用场景

访问者模式结构较为复杂,但是访问者模式将同一类操作封装在一个访问者中,使得相关的操作彼此集中,提高了代码的可读性和维护性。它常用于对象结构比较稳定,但经常需要在此对象结构上定义新的操作,这样就无需修改现有的元素类,只需要定义新的访问者来添加新的操作。


本站由 卡卡龙 使用 Stellar 1.29.1主题创建

本站访问量 次. 本文阅读量 次.