Java设计模式系列之访问者模式
访问者模式,顾名思义使用了这个模式后就可以在不修改已有程序结构的前提下,通过添加额外的“访问者”来完成对已有代码功能的提升。
《设计模式》一书对于访问者模式给出的定义为:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的 新操作。从定义可以看出结构对象是使用访问者模式必须条件,而且这个结构对象必须存在遍历自身各个对象的方法。这便类似于java中的 collection概念了。
以下是访问者模式的组成结构:
1) 访问者角色(Visitor):为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。
2) 具体访问者角色(Concrete Visitor):实现每个由访问者角色(Visitor)声明的操作。
3) 元素角色(Element):定义一个Accept操作,它以一个访问者为参数。
4) 具体元素角色(Concrete Element):实现由元素角色提供的Accept操作。
5) 对象结构角色(Object Structure):这是使用访问者模式必备的角色。它要具备以下特征:能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序集合。
来张类图就能更加清晰的看清访问者模式的结构了。
那么像引言中假想的。我们应该做些什么才能让访问者模式跑起来呢?首先我们要在原有的类层次结构中添加accept方法。然后将这个类层次中的类放到一个对象结构中去。这样再去创建访问者角色……
三、举例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<b> public interface Person { void accept(Visitor visitor); } public class Woman implements Person{ public void accept(Visitor visitor) { visitor.visit( this ); } } public class Man implements Person{ public void accept(Visitor visitor) { visitor.visit( this ); } }</b> |
访问者接口与实现类,分别代表男人与女人在不同的状态下的表现
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
|
public interface Visitor { public void visit(Man man); public void visit(Woman girl); } //成功时Man与Woman的不同表现 public class Success implements Visitor{ public void visit(Man man) { System.out.println( "当男人成功时,背后多半有一个伟大的女人" ); } public void visit(Woman woman) { System.out.println( "当女人成功时,背后大多有一个不成功的男人" ); } } //恋爱时Man与Woman的不同表现 public class Love implements Visitor{ public void visit(Man man) { System.out.println( "当男人恋爱时,凡事不懂也装懂" ); } public void visit(Woman girl) { System.out.println( "当女人恋爱时,遇事懂也装不懂" ); } } |
ObjectStructure与客户端测试代码
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
|
import java.util.*; public class ObjectStructure { private List<Person> elements = new ArrayList<Person>(); public void attach(Person element){ elements.add(element); } public void detach(Person element){ elements.remove(elements); } //遍历各种具体元素并执行他们的accept方法 public void display(Visitor visitor){ for (Person p:elements){ p.accept(visitor); } } } public class Client { public static void main(String[] args) { ObjectStructure o = new ObjectStructure(); //依赖于ObjectStructure //实例化具体元素 o.attach( new Man()); o.attach( new Woman()); //当成功时不同元素的不同反映 Visitor success = new Success(); //依赖于抽象的Visitor接口 o.display(success); //当恋爱时的不同反映 Visitor amativeness = new Love(); //依赖于抽象的Visitor接口 o.display(amativeness); } } |
既定访问者模式的类图: