2012-02-14 6 views
2

Javaで外部プログラム用の新しいスクリプトジェネレータを作成しています。この言語は変数をサポートしますが、型指定されていない言語です。通常、VaRの型がfloatであるJava - 値の型を認識するためのパターン

public class Var 
{ 
    private String name; 
    private String type; 
    private float defaultValue; 
    private float lowerBound; 
    private float upperBound; 
    private float value; 
    private LinkedList<Float> valuesConstraint; 
    private String description; 
    private Category category; 
    private LinkedList<CvarDependency> dependencies; 
    ... 
} 

、それはまた、ブール[0 | 1]することができ、文字列、またはINT:これは私が最初に書かれているコードの例です。 は、だから私はこの実装を行うために終わった:

abstract class Var 
{ 
    private String name; 
    ... 
} 

public class IntVar extends Var 
{ 
    private int value; 
    private int defaultValue; 
    private int lowerBound; //-infinite 
    private int upperbound; //+infinite 
    ... 
} 

public class FloatVar extends Var 
{ 
    private float value; 
    private float defaultValue; 
    private float lowerBound; //-infinite 
    private float upperbound; //+infinite 
    ... 
} 

public class StringVar extends Var 
{ 
    private String value; 
    private String defaultValue; //empty string 
    ... 
} 

public class BoolVar extends Var 
{ 
    private boolean value; 
    private boolean defaultValue; 
    private boolean lowerBound; //false <-> 0 
    private boolean upperbound; //true <-> 1 
    ... 
} 

今、私がLinkedListのにそれらのVARSを保存する必要がありますが、私は、適切なキャストを管理しますどのようにその内容を読まなければならないとき?

Var var = Manager.getVar("namevar"); 
if(var.getClass().getName().equals("StringVar")) 
    ... 
else if(var.getClass().getName().equals("IntVar")) 
    ... 
else if(var.getClass().getName().equals("FloatVar")) 
    ... 
else if(var.getClass().getName().equals("BoolVar")) 
    ... 

良く、この問題に対処するために、任意のヒント:私は、このアプローチを使用することをお勧めではないことを読んだことがありますか?

+0

「Var」ごとに「訪問者」パターンを提案します。そうすれば、訪問者はキャスティングの仕方を知ることができます。 –

+0

これは私が必要としたパターンです。このコメントを回答として投稿してください。これを返信のスタックの上に置くことができます! – Otacon

+0

instanceOf演算子を使用できますか? – basav

答えて

0

クラスを比較し、クラスの名前を比較しないでください:

if(var.getClass().equals(IntVar.class)) { 
    IntVar intVar = (IntVar) var; 
    ... 

ます。またvar instanceof IntVarを使用することができますが、あなたはIntVarを拡張するクラスを記述する場合には、問題を引き起こす可能性があります。

+0

ニース、ありがとう、それは "良い練習"ですか? :) – Otacon

+0

はい、そうです。しかし、比較の前に、varが 'null 'でないことを確認する必要があります。 – Stephan

+0

確かにそしてthx;) – Otacon

0

public class Var<T extends Comparable<T>> 
{ 
    private String name; 
    private String type; 
    private T defaultValue; 
    private T lowerBound; 
    private T upperBound; 
    private T value; 
    private LinkedList<T> valuesConstraint; 
    private String description; 
    private Category category; 
    private LinkedList<CvarDependency> dependencies; 
    ... 
} 
+0

実際に私はいくつかの操作を行う必要があります。 int、bool、floatのdefaultValue、lowerBound、upperBoundは簡単に管理できますが、Stringsは管理しません! – Otacon

0

ではなく、それはおそらく、でしょう、あなたのインタプリタエキスを有し、かつ、直接値を操作...あなたはジェネリック型を使用することができますが、私はあなたがメンバーと何をする必要があるか分かりません異なるアプローチを取って、このような方法として操作を定義する方がよい:

abstract class Var 
{ 
    ... 
    public Var add(Var var); // corresponds to var + otherVar; in script 
    public Var subtract(Var var); // corresponds to var - otherVar; in script 
    public Var unarySubtract(); // corresponds to -var; in script 
    ... 
} 

あなたはこれらのメソッドを呼び出すことにより、スクリプト内の式を評価することができ、そして、あなたのクラスは、例えばオーバーライドして、このような過負荷することができますこの方法:

public class IntVar extends Var 
{ 
    ... 
    public IntVar add(IntVar var) 
    { 
     return new IntVar(value + var.value); // add another int 
    } 
    public FloatVar add(FloatVar var) 
    { 
     return new FloatVar(value + var.value); // add another float (and cast result to float? up to you whether you want to do this...) 
    } 
    public StringVar add(StringVar var) 
    { 
     return new StringVar("" + value + var.value); // add a string, and cast to string (for string concatenation) 
    } 
    public Var add(Var var) 
    { 
     throw new OperationNotSupportedException(); // no other types can be added to an IntValue so throw an exception 
    } 
    public Var subtract(Var var) {...} 
    public IntVar unarySubtract() 
    { 
     return new IntVar(-value); 
    } 
    ... 
} 

このようにして、インタープリタで直接値を処理しなくても、操作を実装して評価できます。

このメソッドを使用すると、ユーザーが不正なスクリプトを実行しようとすると(たとえば、BoolVarをIntVarに追加しようとすると)、インタプリタに例外がスローされます。

public Var add(Var var) 
{ 
    throw new OperationNotSupportedException(); // no other types can be added to an IntValue so throw an exception 
} 

そして操作のみの安全な使用法とオーバーライド/過負荷:

おそらく、あなたもあなたの抽象ヴァールクラスでの操作のデフォルトの実装は、ちょうどこのことかもしれません。

ここで 'コンテンツを読む'と言うとき、おそらくタイプのインスタンスのコンテンツは、出力のためだけのものであれば、少なくともある時点で一様に処理する必要があります抽象的な 'toString()'メソッドを持っていますか?出力以外の目的であれば、他のtoX()メソッドだけでなく、それぞれの型インスタンスを同じ方法で扱うことができないのは、どのような目的ですか?

これはあなたの質問に直接答えるものではなく、むしろ問題を完全に回避するために別のアプローチを提案しています。これは、あなたが達成しようとしていることについて何かばかげた仮定をしたかもしれない/ o問題の文脈の詳細を見ているが、それでも役に立つと思う。

これは役に立たない場合は、いくつかの情報を提供してください。もう少し手伝ってください。私は現在のアプローチを続けることをお勧めできませんが、これ以外に何を提案するのかは不明です。

編集:私の悪いことを待って、質問を正しく読まなかった。これは通訳ではなく、ジェネレータです。どんな発電機?どの言語のスクリプトの生成器ですか?まあ、それは重要な問題ではないかもしれませんが、私はあなたが達成する必要があることについて本当に多くを理解していないことを実感した質問を読み返しました。

私はまだ、一般的にカプセル化が訪問者パターンよりも優れた選択だと考えています。もちろん、Varによって提供されるインターフェイスを介して各変数に既に割り当てられている動作からその動作を構築できないような方法で、任意の変数で動作する動作を追加する必要がある場合は、何らかの理由があります。これは?出力するには、必ず各変数をすべての文字に共通の形式で読み込む必要があります。なぜなら、toString()、toSomething()、toAnotherThing()などの理由だけではないからです。

0

私の提案はVisitorパターン。アルゴリズムはオブジェクトVar(およびサブクラス)ではなく、Visitorに配置されます。

public class Var { 

    public void accept(VarVisitor visitor) { 
     visitor.visit(this); 
    } 
} 

ビジター

public interface VarVisitor { 
    public void visit(FloatVar var); 
    public void visit(IntVar var); 
    public void visit(StringVar var); 
    public void visit(BoolVar var); 

    //...etc. 
    public Object getValue(); 
} 

VisitorImpl

public class VarVisitorImpl implements VarVisitor { 
    private Object value; 

    @Override 
    public Object getValue() { 
     return value; 
    } 

    @Override 
    public void visit(FloatVar var) { 

    } 

    @Override 
    public void visit(IntVar var) { 

    } 

    @Override 
    public void visit(StringVar var) { 

    } 

    @Override 
    public void visit(BoolVar var) { 

    } 
} 

私は、これはあなたが達成したいかについてのアイデアを提供したいと考えています。

関連する問題