1. 基本概念
访问者模式(Visitor Pattern)是一种行为型设计模式,可以在不改变对象结构的前提下,对对象中的元素进行新的操作。
2. 基本结构
访问者模式包括以下几个基本角色:
- 抽象访问者(Visitor): 声明了访问者可以访问哪些元素,以及如何访问它们的方法
visit
。
- 具体访问者(ConcreteVisitor): 实现了抽象访问者定义的方法,不同的元素类型可能有不同的访问行为。医生、管理员、游客都属于具体的访问者,它们的访问行为不同。
- 抽象元素(Element): 定义了一个accept方法,用于接受访问者的访问。
- 具体元素(ConcreteElement): 实现了accept方法,是访问者访问的目标。
- 对象结构(Object Structure): 包含元素的集合,可以是一个列表、一个集合或者其他数据结构。负责遍历元素,并调用元素的接受方法。
3. 简易实现
- 定义抽象访问者: 声明那些元素可以访问
1 2 3 4 5
| interface Visitor { void visit(ConcreteElementA element); void visit(ConcreteElementB element); }
|
- 实现具体访问者:实现具体的访问逻辑
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
| 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"); } }
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 2 3 4
| interface Element { void accept(Visitor visitor); }
|
- 实现具体元素:实现接受访问者的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class ConcreteElementA implements Element { @Override public void accept(Visitor visitor) { visitor.visit(this); } }
class ConcreteElementB implements Element { @Override public void accept(Visitor visitor) { visitor.visit(this); } }
|
- 创建对象结构:提供一个接口让访问者访问它的元素。
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 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. 使用场景
访问者模式结构较为复杂,但是访问者模式将同一类操作封装在一个访问者中,使得相关的操作彼此集中,提高了代码的可读性和维护性。它常用于对象结构比较稳定,但经常需要在此对象结构上定义新的操作,这样就无需修改现有的元素类,只需要定义新的访问者来添加新的操作。