2

私は、バイナリ表現、単項表現、すべて抽象的な、Add、Sub、Mulなどの具体的な具体的なクラスに展開する式のクラス構造を持っています、そうでない、など...そのように。Java - 同じクラス構造の複数の訪問者パターン

Class Structure

私は、これらのクラスのそれぞれに2人の訪問者を作成したいです。 1つはtoString、もう1つは式を評価する(値を計算する)。

私の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); 

} 

のみのtoStringの訪問者のためにevaluateVisitorのために働くとはないだろう、今持っているもの例えば

また、例えば使用しての違いは何です:

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>を実装し、他の2つはVisitor<Integer>Visitor<Boolean>を実装します。

visit()とvisitNeg()の使用に関しては、選択の問題です。別の名前を使用するとAPIが乱雑になると感じる人もいます。いくつかはオーバーロードを使用して、理解するのがより複雑になり、バグが発生しやすいと感じています。私は個人的に過負荷の大きなファンではありません。

+0

これを実装する際に問題があります。たとえば、変数の戻り値の型を必要とするクラスがあります。そして、それぞれのEvaluate訪問者に 'public visit(Sequence c)'のようなものを実装しようとしていますが、 'Evaluator.java:147:error:invalid method declarationのようなコンパイラエラーがあります。戻りタイプが必要です 公開 visitSequence(シーケンスc) ' – spacing

+0

いいえ適切な構文が表示されませんでした。私は今クラスの一般的な名前を定義しなければならないことに気付きました。また、ブラケットをもう一度使用しない方法で – spacing

関連する問題