2

所以我有一个表达式的类结构,由二进制表达式,一元表达式,所有抽象构成,这些表达式扩展成它们具体的具体操作类,如Add,Sub,Mul ,不,等等......就像这样。Java - 同一类结构的多个访问者模式

Class Structure

我希望为每个类2人次。一个用于toString,另一个用于评估表达式(计算值)。

问题是,我的toStringVisitor应该总是返回一个String,但是evaluateVisitor将根据操作返回变量类型(即:Add将返回一个int,Lower或Not将返回一个布尔值,其他一些将返回其他值类型)

我可以避免为这2位访客创建2个访客界面吗?

比如我现在所拥有的

public interface Visitor { 

Public int visit(Neg c); 
Public int visit(Add c); 
Public int visit(Sub c); 
Public int visit(Mul c); 
Public boolean visit(Lowerthan c); 
Public boolean visit(Greaterthan c); 
Public boolean visit(Equal c); 
Public boolean visit(Not c); 
Public boolean visit(And c); 
Public boolean visit(Or c); 

} 

只会为evaluateVisitor而不是针对游客的toString工作。

另外,就是使用例如之间的区别:

Public int visit(Neg c); 
Public int visit(Add c); 
Public int visit(Sub c); 
Public int visit(Mul c); 

Public int visitNeg(Neg c); 
Public int visitAdd(Add c); 
Public int visitSub(Sub c); 
Public int visitMul(Mul c); 

有人告诉我,我应该区分访问方法来避免动态绑定的问题,但我真的不能弄清楚为什么会是这种情况。

回答

4

可以使访问者通用:

interface Visitor<R> { 
    R visit(Neg c); 
    ... 
} 

所以你ToStringVisitor将实施Visitor<String>,而另外两个将实施Visitor<Integer>Visitor<Boolean>

关于使用visit()和visitNeg(),这是一个选择问题。有些人觉得使用不同的名称会使API变得混乱。有些人觉得使用重载会让事情变得更加复杂,并且容易出错。我个人不是超载的粉丝。

+0

我在执行此操作时遇到问题。例如,我有一个需要变量返回类型的类。而且我试图在各自的Evaluate访问器中实现类似'public visit(Sequence c)'的操作,但是Im有一个编译器错误,例如Evaluator.java:147:error:invalid method declaration;返回类型 public visitSequence(Sequence c)' – spacing

+0

好吧,我没有得到正确的语法。我现在意识到我必须在类和方法中定义通用名称,我不再使用括号 – spacing