第三篇 遍历对象 第十二章 - 访问者模式

  迭代器模式主要用于遍历类型相同、集中管理的对象,那些类型各异的散落对象又该如何遍历呢?
  我们引用《桃花源记》中的故事,看看访问者模式提供的设计思路。
  假设桃花源中有林、山、人三种类型的对象,误入秘境的武陵人需要挨个“访问”它们。

// 林
public class Grove {}

// 山
public class Mountain {}

// 人
public class Person {}

// 抽象访问者
public interface Visitor {

  // 访林
  public void visit(Grove obj);

  // 访山
  public void visit(Mountain obj);

  // 访人
  public void visit(Person obj);

}

  直接遍历类型各异的散落对象并不容易。
  方便起见,我们先统一受访者的表观类型——使它们实现同一个接口。我们在这个接口里定义好接纳访问者的方法,使访问者有机会了解受访者的内部细节。
  完整的代码如下。

// 抽象受访者
public interface Visitable {

  // 接纳访问者
  public void accept(Visitor visitor);

}

// 林
public class Grove implements Visitable {

  public void show() {
    // 芳草鲜美,落英缤纷。
  }

  @Override
  public void accept(Visitor visitor) {
    visitor.visit(this);
  }

}

// 山
public class Mountain implements Visitable {

  public void describe() {
    // 山有小口,仿佛若有光。
  }

  @Override
  public void accept(Visitor visitor) {
    visitor.visit(this);
  }

}

// 人
public class Person implements Visitable {

  public void live() {
    // 黄发垂髫,并怡然自乐。
  }

  @Override
  public void accept(Visitor visitor) {
    visitor.visit(this);
  }

}

  表观类型统一后,可以将受访对象放到容器里集中管理。
  如下所示。

// 桃花源
public class PeachStream {

  // 对象容器
  java.util.List<Visitable> list = new java.util.ArrayList<>();

  // 添加对象
  public boolean add(Visitable obj) {
    return this.list.add(obj);
  }

  // 使用迭代器模式遍历容器中的对象
  public void accept(Visitor visitor) {
    for (Visitable obj : list) {
      obj.accept(visitor);
    }
  }

}

  至此,武陵人可以轻松访问桃花源中的林、山、人了。

// 具体访问者
public class WulingVisitor implements Visitor {

  // 访林
  @Override
  public void visit(Grove obj) {
    obj.show();
  }

  // 访山
  @Override
  public void visit(Mountain obj) {
    obj.describe();
  }

  // 访人
  @Override
  public void visit(Person obj) {
    obj.live();
  }

}

// 测试类
public class Test {

  public void test() {
    PeachStream obj = new PeachStream();// 桃花源
    obj.add(new Grove());// 林
    obj.add(new Mountain());// 山
    obj.add(new Person());// 人
    obj.accept(new WulingVisitor());// 武陵人开始访问
  }

}
posted on 2025-03-25 22:21  星辰河岳  阅读(28)  评论(0)    收藏  举报