前言

正文

介绍

我的理解是,利用多态特点,也就是在运行时确定对象的实际类型的特点,来间接让单分派语言实现双分派。简单的说,就是让下面的代码合理

场景类

  1. package cn.zjm404.stu.dp.behavior.visitor;
  2. public class Client {
  3. public static void main(String[] args) {
  4. AbstractObject ao = new ConcreteObject1();
  5. Executor executor = new Executor();
  6. executor.doSomething(ao);
  7. }
  8. }

执行类

  1. package cn.zjm404.stu.dp.behavior.visitor;
  2. public class Executor implements Visitor{
  3. @Override
  4. public void visit(ConcreteObject1 co1) {
  5. System.out.println("co1 执行");
  6. }
  7. @Override
  8. public void visit(ConcreteObject2 co2) {
  9. System.out.println("co2 执行");
  10. }
  11. }

Bean

AbstractObject 与 ConcreteObject1,ConcreteObject2 关系如下 访问者模式 - 图1至于为什么需要实现这个功能,在“使用”进行介绍。先看如何实现

实现

以上代码问题出在无法确定调用对象的哪个方法,对于对象调用哪个方法,是在编译阶段确定的,而使用参数的父类,并无法在编译阶段确定具体的调用方法。会出现问题
image.png
如何实现呢?正如介绍中说的那样,多态特性保证了可以在运行时确定对象的实际类型,那么可以借用这种特性,在确定对象之后,再确定方法,实现方式就是将当前对象传递过去。代码如下

中间类

  1. package cn.zjm404.stu.dp.behavior.visitor;
  2. public interface Visitor {
  3. public void doSomething(ConcreteObject1 co1);
  4. public void doSomething(ConcreteObject2 co2);
  5. }

执行类

  1. package cn.zjm404.stu.dp.behavior.visitor;
  2. public abstract class AbstractObject {
  3. public abstract void accept(Visitor visitor);
  4. }
  1. package cn.zjm404.stu.dp.behavior.visitor;
  2. public class Executor implements Visitor{
  3. @Override
  4. public void doSomething(ConcreteObject1 co1) {
  5. System.out.println("co1 执行");
  6. }
  7. @Override
  8. public void doSomething(ConcreteObject2 co2) {
  9. System.out.println("co2 执行");
  10. }
  11. }

Bean

  1. package cn.zjm404.stu.dp.behavior.visitor;
  2. public class ConcreteObject1 extends AbstractObject{
  3. @Override
  4. public void accept(Visitor visitor) {
  5. visitor.doSomething(this);
  6. }
  7. }
  1. package cn.zjm404.stu.dp.behavior.visitor;
  2. public class ConcreteObject2 extends AbstractObject {
  3. @Override
  4. public void accept(Visitor visitor) {
  5. visitor.doSomething(this);
  6. }
  7. }

场景类

  1. package cn.zjm404.stu.dp.behavior.visitor;
  2. public class Client {
  3. public static void main(String[] args) {
  4. AbstractObject ao = new ConcreteObject1();
  5. Executor executor = new Executor();
  6. // executor.doSomething(ao);
  7. ao.accept(executor);
  8. }
  9. }