# 访问者 (Visitor)

当想要为对象的组合增加新的能力且封装并不重要时,就可以使用访问者模式。

现在需要知道的就是,被访问的类需要将自身引用传入访问者。讲起来比较空泛,所以先看代码。

# 实现

代码来自菜鸟教程。

  • 定义表示元素的接口:
public interface ComputerPart {
    // 接口定义的行为:元素提供一个方法供访问者进入
    // 假设存在 ComputerPartVisitor 接口定义了访问者的 visit 行为
    public void accept(ComputerPartVisitor computerPartVisitor);
}
  • 创建扩展上述类的实体类
// 创建一个键盘实体类
public class Keybord implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
        // 实体类实现的行为是:将自己的引用 this 暴露给外部访问者
        computerPartVisitor.visit(this);
    }
}
// 创建一个监视器实体类
public class Monitor implements ComputerPart {
    @Override
    publicvoid accept(ComputerPartVisitor computerPartVisitor) {
        computerPartVisitor.visit(this);
    }
}
// 创建一个鼠标实体类
public class Mouse  implements ComputerPart {
   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      computerPartVisitor.visit(this);
   }
}
  • 再写一个总体的类
public class Computer implements ComputerPart {
	ComputerPart[] parts;
    
    public Computer() {
        parts = new ComputerPart[] {
            new Mouse(),new Keyboard(),new Monitor()
        };
        
        @Override
        public void accept(ComputerPartVisitor computerPartVisitor) {
            for(int i = 0;i < n;i++) {
                parts[i].accept(computerPartVisitor);
            }
            computerPartVisitor.visit(this);
        }
    }
}
  • 创建一个实体访问者类
public class ComputerPartDisplayVisitor implements ComputerPartVisitor {
 
   @Override
   public void visit(Computer computer) {
      System.out.println("Displaying Computer.");
   }
 
   @Override
   public void visit(Mouse mouse) {
      System.out.println("Displaying Mouse.");
   }
 
   @Override
   public void visit(Keyboard keyboard) {
      System.out.println("Displaying Keyboard.");
   }
 
   @Override
   public void visit(Monitor monitor) {
      System.out.println("Displaying Monitor.");
   }
}
  • 最后运行一下
public class VisitorPatternDemo {
   public static void main(String[] args) {
 
      ComputerPart computer = new Computer();
      computer.accept(new ComputerPartDisplayVisitor());
   }
}

# 总结

代码逻辑简单:

  • 访问者有处理被访问者的行为。
  • 被访问者有接收访问者并将自身引用暴露给访问者的行为。

# 参考

菜鸟教程:https://www.runoob.com/design-pattern/visitor-pattern.html?_=1478060039

Java 全栈知识体系:https://pdai.tech/md/dev-spec/pattern/20_visitor.html