目录
  1. 1. 访问者模式
    1. 1.1. 定义
    2. 1.2. 访问者模式示意图
    3. 1.3. 流程
    4. 1.4. 代码实现
      1. 1.4.1. 元素
      2. 1.4.2. 访问者
      3. 1.4.3. 对象结构
      4. 1.4.4. 场景实现
    5. 1.5. 应用场景
    6. 1.6. 访问者模式的优点和缺点
      1. 1.6.1. 优点
      2. 1.6.2. 缺点
访问者模式

访问者模式

定义

Represent an operation to be performed on the elements of an objects structure.Vistor lets you define a new operation without changing the classes of the elements on which it operates.
封装一些作用于某种数据结构中的各元素操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

访问者模式示意图

访问者模式

流程

  1. 客户获取需要的信息,首先需要让对象结构生产出元素对象。
  2. 元素先接受访问者的访问,访问者就可以获取生产的元素对象。
  3. 访问者就可以按自己的方式操作元素对象,获得客户端需要的信息。
  4. 最终客户端能够得到需要的信息。

代码实现

元素

  1. 创建所有元素的抽象类
1
2
3
4
5
6
7
8
9
/**
* 元素的抽象类,定义所有元素共同操作
*/
public abstract class Element {
/* 元素的动作 */
public abstract void test();
/* 元素接受访问者访问,访问者可以在自己那里定义访问动作 */
public abstract void accept(IVisitor visitor);
}
  1. 创建继承抽象类的具体元素1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 元素1的实现类
*/
public class ConcreteElement1 extends Element {
@Override
public void test() {
System.out.println("元素1");
}

/**
* 接受访问者的访问,并将产生的元素对象送给访问者,让访问者操作元素对象
* @param visitor
*/
@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
  1. 创建继承抽象类的具体元素2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 元素2的实现类
*/
public class ConcreteElement2 extends Element{
@Override
public void test() {
System.out.println("元素2");
}

/**
* 接受访问者的访问,将元素2的对象送给访问者,让访问者能操作元素2的对象
* @param visitor
*/
@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}

访问者

  1. 创建所有访问者需要实现的接口
1
2
3
4
5
6
7
8
9
/**
* 访问者接口
*/
public interface IVisitor {
/* 用于访问元素1 */
public void visit(ConcreteElement1 element1);
/* 用于访问元素2 */
public void visit(ConcreteElement2 element2);
}
  1. 创建访问者,这个访问者能够访问元素1和元素2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 访问者
*/
public class ConcreteVisitor implements IVisitor {

/**
* 访问者访问元素1的方法,元素1接受了访问者的访问,访问者能够获取到元素1的对象,然后在这个方法中自由操作元素对象
* @param element1
*/
@Override
public void visit(ConcreteElement1 element1) {
element1.test();
}

/**
* 访问者访问元素2的方法,元素1接受了访问者的访问,访问者能够获取到元素2的对象,然后在这个方法中自由操作元素对象
* @param element2
*/
@Override
public void visit(ConcreteElement2 element2) {
element2.test();
}
}

对象结构

  1. 创建一个用来生产元素对象的对象结构
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 对象结构,用来生产元素对象,这里随机生产出元素1或者元素2
*/
public class ObjectStructure {
public static Element createElement(){
Random random = new Random();
if (random.nextInt(100) > 50) {
return new ConcreteElement1();
}else {
return new ConcreteElement2();
}
}
}

场景实现

1
2
3
4
5
6
7
8
9
10
11
public class Test{
public static void main(String[] args) {
for (int i=0 ; i<10 ; i++){
/* 创建元素对象 */
Element element = ObjectStructure.createElement();
/* 让元素接受访问者的访问 */
/* 接受访问后,访问者就获取元素对象,操作元素对象 */
element.accept(new ConcreteVisitor());
}
}
}

应用场景

  1. 一个对象结构有很多不同接口的对象,我们需要对这些对象实施依赖具体类的操作。
  2. 需要对一个对象结构中的对象进行很多不同且不相关的操作。
  3. 访问者模式使迭代器模式的扩展,当迭代器不能胜任,我们能使用访问者模式。

访问者模式的优点和缺点

优点

  1. 符合单一职责原则,元素只负责加载数据,访问者只负责展现数据,对象结构只负责创建对象。
  2. 扩展性非常好。对数据的操作很快捷,如果要增加操作,只需要在访问者中增加对应方法就行了。
  3. 非常好的灵活性。

缺点

  1. 具体元素对访问者公开,违反迪米特原则。
  2. 具体元素变更很困难。
  3. 访问者直接访问具体元素,违反了依赖倒置原则。
文章作者: rack-leen
文章链接: http://yoursite.com/2019/05/19/Java/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E8%A1%8C%E4%B8%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F/%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 rack-leen's blog
打赏
  • 微信
  • 支付宝

评论