访问者

63 阅读2分钟

访问者模式(Visitor Pattern)是一种行为型模式,它将一个操作从一个对象的类层次结构中分离出来,并封装在一个独立的对象中。访问者可以访问该类层次结构中的所有对象,并执行操作。

访问者模式的主要角色如下:

  • 抽象元素(Element):定义了访问者可以访问和操作的接口。
  • 具体元素(ConcreteElement):实现了抽象元素接口,并提供了访问者可以操作的具体实现。
  • 抽象访问者(Visitor):定义了对所有具体元素执行操作的接口。
  • 具体访问者(ConcreteVisitor):实现了抽象访问者接口,并定义了对具体元素的具体操作。

访问者模式的实现如下:

// 抽象元素
public interface Element {
  void accept(Visitor visitor);
}

// 具体元素1
public class ConcreteElement1 implements Element {
  @Override
  public void accept(Visitor visitor) {
    visitor.visit(this);
  }
}

// 具体元素2
public class ConcreteElement2 implements Element {
  @Override
  public void accept(Visitor visitor) {
    visitor.visit(this);
  }
}

// 抽象访问者
public interface Visitor {
  void visit(ConcreteElement1 element1);
  void visit(ConcreteElement2 element2);
}

// 具体访问者1
public class ConcreteVisitor1 implements Visitor {
  @Override
  public void visit(ConcreteElement1 element1) {
    System.out.println("具体访问者1访问了具体元素1");
  }

  @Override
  public void visit(ConcreteElement2 element2) {
    System.out.println("具体访问者1访问了具体元素2");
  }
}

// 具体访问者2
public class ConcreteVisitor2 implements Visitor {
  @Override
  public void visit(ConcreteElement1 element1) {
    System.out.println("具体访问者2访问了具体元素1");
  }

  @Override
  public void visit(ConcreteElement2 element2) {
    System.out.println("具体访问者2访问了具体元素2");
  }
}

public class Main {
  public static void main(String[] args) {
    // 创建元素
    Element element1 = new ConcreteElement1();
    Element element2 = new ConcreteElement2();

    // 创建访问者
    Visitor visitor1 = new ConcreteVisitor1();
    Visitor visitor2 = new ConcreteVisitor2();

    // 访问元素
    element1.accept(visitor1);
    element2.accept(visitor1);
    element1.accept(visitor2);
    element2.accept(visitor2);
  }
}

输出:

具体访问者1访问了具体元素1
具体访问者1访问了具体元素2
具体访问者2访问了具体元素1
具体访问者2访问了具体元素2

访问者模式的优点如下:

  • 将操作从元素对象中分离出来,提高了对象的独立性和复用性。
  • 可以通过访问者对象动态地改变元素对象的行为。

访问者模式的应用场景如下:

  • 需要对一个对象的类层次结构中的所有对象执行相同的操作时。
  • 需要动态地改变对象的行为时。

访问者模式的注意事项如下:

  • 访问者对象的数量不宜过多,否则会导致系统的复杂性增加。
  • 访问者对象的实现要尽量通用,以便可以适应不同的元素对象。