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