定义
封装作用于某数据结构(如List/Set/Map等)中的各元素的操作;
可以在不改变各元素的类的前提下,定义作用于这些元素的操作;
行为型
适用场景
- 一个数据结构(如List/Set/Map等)包含很多类型对象
- 数据结构与数据操作分离
优点和缺点
优点
缺点
结构
- 抽象访问者角色:定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作visit(),该操作中的参数类型标识了被访问的具体元素;
- 具体访问者角色:实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么;
- 抽象元素角色:声明一个包含接受操作accept()的接口,被接受的访问者对象作为accept()方法的参数;
- 具体元素角色:实现抽象元素角色提供的accept()操作,其方法通常都是visitor.visit(this),另外具体元素中可能还包含本身业务逻辑的相关操作。
- 对象结构角色:是一个包含元素角色的容器,提供让访问者对象遍历容器中的多有元素的方法,通常由List/Set/Map等聚合类实现。
代码实现
假设一个场景,双十一购物,有几个小伙伴买了商品,有的想给差评,有的想给好评
抽象访问者角色
想要做出的评论的抽象,比如好评、差评
1 2 3 4
| public interface Visitor { void visit(ConcreteElementA element); void visit(ConcreteElementB element); }
|
具体访问者角色
具体的评论,比如好评差评
1 2 3 4 5 6 7 8
| public class ConcreteVisitorA implements Visitor { public void visit(ConcreteElementA element) { System.out.println("具体访问者A访问-->" + element.operationA()); } public void visit(ConcreteElementB element) { System.out.println("具体访问者A访问-->" + element.operationB()); } }
|
具体访问者
1 2 3 4 5 6 7 8
| public class ConcreteVisitorB implements Visitor { public void visit(ConcreteElementA element) { System.out.println("具体访问者B访问-->" + element.operationA()); } public void visit(ConcreteElementB element) { System.out.println("具体访问者B访问-->" + element.operationB()); } }
|
抽象元素角色
用户的抽象,里面有一个评论的方法
1 2 3
| public interface Element { void accept(Visitor visitor); }
|
具体元素
用户实现具体的评论,并记录有用户的名称
1 2 3 4 5 6 7 8
| public class ConcreteElementA implements Element { public void accept(Visitor visitor) { visitor.visit(this); } public String operationA() { return "具体元素A的操作。"; } }
|
具体元素
1 2 3 4 5 6 7 8
| public class ConcreteElementB implements Element { public void accept(Visitor visitor) { visitor.visit(this); } public String operationB() { return "具体元素B的操作。"; } }
|
对象结构角色
记录有所有的购买用户,只有这些用户可以进行评价
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class ObjectStructure { private List<Element> list = new ArrayList<>(); public void accept(Visitor visitor) { Iterator<Element> i = list.iterator(); while (i.hasNext()) { ((Element) i.next()).accept(visitor); } } public void add(Element element) { list.add(element); } public void remove(Element element) { list.remove(element); } }
|
测试:
1 2 3 4 5 6 7 8 9 10 11 12
| public class Test { public static void main(String[] args) { ObjectStructure os = new ObjectStructure(); os.add(new ConcreteElementA()); os.add(new ConcreteElementB()); Visitor visitor = new ConcreteVisitorA(); os.accept(visitor); System.out.println("------------------------"); visitor = new ConcreteVisitorB(); os.accept(visitor); } }
|
结果:
1 2 3 4 5
| 具体访问者A访问-->具体元素A的操作。 具体访问者A访问-->具体元素B的操作。 ------------------------ 具体访问者B访问-->具体元素A的操作。 具体访问者B访问-->具体元素B的操作。
|
UML类图