设计模式(22)-访问者模式

Visitor
思想:表 示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
场景:其 实你不用去理解上面这句话。该模式其实又是一个在代码的物理结构上和Bridge模式很相似的模 式。但是,其语义,其目的,在逻辑上又是不同的。如果说Bridge,以及上述我称为可视为Bridge扩 展的模式中,作为参数的Bridge类,是作为调用类的被访问对象的话,Visitor, 在大多数情形下,如其英文含义,它在语义上是完全相反的。不是他被调用的类处理,更大程度上它处于主动状态,是它去访问,去处理调用它的类。调用它的类, 把自己对别人隐藏起来的东西,暴露给Visitor品尝,任君蹂躏(这个,这个~~千 万别想歪了;-))。另一方面,即使逻辑上没有这种Visitor主 动去访问调用类的语义,只要Visitor类中的操作,是依赖于调用类的具体实现类(它本身或他某 个层次的子类)的某些状态或者方法的,那么,就可以应用该模式来分离出这样的可重用的操作。

实现:类 似Bridge模式。
重构成本:中。
Visitor访问者设计模式是在不修改已有程序结构的前提下,通过添加额外的“访问者”来完成对已有代码功能的提升。
Visitor访问者设计模式的角色:
(1) 访问者角色(Visitor):声明一个访问接口。接口的名称和方法的参数标识了向访问者发送请求的元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。
(2) 具体访问者角色(Concrete Visitor):实现访问者角色(Visitor)接口
(3)元素角色(Element):定义一个Accept操作,它以一个访问者为参数。
(4) 具体元素角色(Concrete Element):实现元素角色(Element)接口。
(5) 对象结构角色(Object Structure):具体元素的集合,提供一个高层的接口允许访问者角色访问它的元素。
Visitor访问者设计模式结构如下:
这里写图片描述
Visitor访问者设计模式例子代码如下:

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

//抽象元素
interface IElement{
public void accept(IVisitor visitor);
}
//具体元素
class ElementA implements IElement{
public void accept(IVisitor visitor){
visitor.visit(this);
}
public void operationA(){
System.out.println(“ElementA do operationA()……”);
}
}
class ElementB implements IElement{
public void accept(IVisitor visitor){
visitor.visit(this);
}
public void operationB(){
System.out.println(“ElementB do operationB()……”);
}
}
class ElementC implements IElement{
public void accept(IVisitor visitor){
visitor.visit(this);
}
public void operationC(){
System.out.println(“ElementC do operationC()……”);
}
}
//抽象访问者
interface IVisitor{
public void visit(ElementA element);
public void visit(ElementB element);
public void visit(ElementC element);
}
//具体访问者
class MyVisitor implements IVisitor{
public void visit(ElementA element){
element.operationA();
}
public void visit(ElementB element){
element.operationB();
}
public void visit(ElementC element){
element.operationC();
}
}
Public class VisitorDemo{
public static void main(String[] args){
IElement[] list = {new ElementA(), new ElementB(), new ElementC()};
IVisitor visitor = new MyVisitor();
for(int i = 0; i < list.length; i++){
list[i].accept(visitor);
}
}
}

Visitor访问者设计模式有以下两个特点:
(1).对元素的访问不是访问者主动发起的,而是通过元素接收访问者来访问自己。
(2).对元素的操作不是元素自己主动调用,而是通过访问者的访问方法来操作元素。
JDK中访问者模式的应用:
•javax.lang.model.element.Element和javax.lang.model.element.ElementVisitor
•javax.lang.model.type.TypeMirror和javax.lang.model.type.TypeVisitor
•javax.lang.model.element.AnnotationValue和javax.lang.model.element.AnnotationValueVisitor