访问者模式:覆盖与重载

Mat*_*ias 5 java overriding overloading visitor

要在Java中实现访问者模式,您可以使用覆盖或重载.选择是取决于还是总是优先选择其中之一?因为我没有看到任何缺点.因为我认为第一个和第三个例子总能完成这项工作?

访客压倒一切

public interface Visitor {
   public void visitX(X x);
   public void visitY(Y y);
}
public class ConcreteVisitor {
   public void visitX(X x) { ... }
   public void visitY(Y y) { ... }
}

public abstract class XY {
   public abstract void accept(Visitor v);
}
public class X extends XY {
   // alternative: one implementation with reflection possible in super class
   public void accept(Visitor v) {
       v.visitX(this);
   }
}
public class Y extends XY {
   // alternative: one implementation with reflection possible in super class
   public void accept(Visitor v) {
       v.visitY(this);
   }
}
Run Code Online (Sandbox Code Playgroud)

访客超载

public interface Visitor {
   public void visit(XY xy); // dummy (couldn't otherwise been used in XY class)
   public void visit(X x);
   public void visit(Y y);
}
public class ConcreteVisitor {
   public void visit(XY xy) { ... }
   public void visit(X x) { ... }
   public void visit(Y y) { ... }
}

public abstract class XY {
   public void accept(Visitor v) {
      v.visit(this); // Which is the compile-time/static type of this? XY?
   }
}
public class X extends XY {

}
public class Y extends XY {

}
Run Code Online (Sandbox Code Playgroud)

更好的访客超载

public interface Visitor {
   public void visit(X x);
   public void visit(Y y);
}
public class ConcreteVisitor {
   public void visit(X x) { ... }
   public void visit(Y y) { ... }
}

public abstract class XY {
   public abstract void accept(Visitor v);
}
public class X extends XY {
   public void accept(Visitor v) {
      v.visit(this);
   }
}
public class Y extends XY {
  public void accept(Visitor v) {
      v.visit(this);
  }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*nik 3

访问者模式本质上是关于用单分派语言覆盖双分派的一个重要用例。它以两步方式利用单分派机制。因此,如果您对这两个步骤之一使用反射,则您不再实现 Visitor。

是否使用重载的问题只是一个小问题,因为它归结为所有visit方法的名称选择。您可以使用其中任何一个,但重载在专业代码中更有意义。在研究该模式时,单独的名称将使您更容易理解访问者模式,该模式因其复杂性而臭名昭著。

  • 我的经验表明,新手很难理解访问者模式,并且重载“visit()”方法会使其变得更加困难。出于这个原因,我现在使用非重载版本。 (3认同)