2011-12-11 13 views
2

私はAndroid/Javaの初心者です。コーディングではなく、言語を使用しています。ループスイッチシーケンスを回避する際のトラブル

私の問題:行ごとに異なる色でcanvas.drawLine()

私は(いくつかの統計分析のために)グラフを描いています。色は配列の値に依存します。その配列(リスト)には、さまざまな型の約20個の変数を持つカスタムオブジェクトが格納されます。

ある時点で、各ドローコールに適切なタイプを取得するためにスイッチが必要ですが、ループ全体では、そのスイッチの結果は同じです。私はプログラムでほぼ終了しているので、パフォーマンスに関する問題を探しています。これは1つです。 グラフは少なくとも1000行を描画するので、スイッチは同じ結果に対して1000回実行されます。

私は配列を持ち、カスタムオブジェクトではない場合、私は単純にintを使用して異なる配列値にアクセスすることができます。しかし、オブジェクトを避けることができるように書き直す方法はありません(他の場所でコードを大きく壊してしまいます)。

今、私はいけない、正直に言うと多型と反射について読んけど...私は完全に理解し、それが防弾ではないいけない何かを実装したい(反射は、エラーを起こしやすいといわれている?!)

私の現在の解決策は、それぞれのケースに対してカスタム描画メソッドを作成したことです。私はループの前に1つのスイッチを持っているし、右のゲッターを使って描画メソッドが動作しています。それは動作しますが、1つの行だけ異なる10のメソッドを持つことは狂っているようです。

また、抽象クラスのこともありますが、上書きされたメソッドがスイッチよりもパフォーマンス上の問題を引き起こさないかどうかは分かりません。私は、Javaが最後に何をするかについて、何かを読んで、そのクロスクラスのメソッド呼び出しがパフォーマンスを損なう可能性がある(私は内部クラス/ネストされたクラスについて、そのクラス外クラスのゲッターを呼び出すことを認めた)。

私はコードをできるだけ短くて可読にしたいので、別のクラスに広がっているのではなく、ひとつのコードブロックにまとめてみたいと思っています。最も重要なことは、私が実装していることを完全に理解していることです。私はいくつかの例をコピー&ペースト 'ここにあなたの方法を入力'とそれが動作して参照してくださいしたくないが、理由や方法を知らない。

だから私は(文句を言わない傷つけるスニペットOFC;)私は実際のコードスニペットよりも、それを行うべきか、実際に理論的で、より興味を持っています)

PS:私はそれを言及すること自由に感じ、どこかにコードのにおいを持っているべき。

いくつかのコード、simplyfiedと問題

Class MyObj { 

    int x; 
    int y; 

    double value_doub; 
    short value_short; 

    // getters and setters etc 
} 


private void draw_graph(int switchcase) { 
    MyObj mObj; 
    int x; 
    int y; 
    double value; 

    for(int i = 0; i < amount_of_values; i++) { 

    mObj = mArrayList.get(i); 

    x = mObj.getx(); 
    y = mObj.gety(); 

    switch(switchcase) { 

    case 0: 
     value = mObj.get_value_doub(); 

     //alternatively, direct field access 
     value = mObj.value_doub; 

     color = calc_color(value, scale_for_this_type); 
    break; 

    case 1: 
     value = (double) mObj.get_value_short(); 

     //alternatively, direct field access 
     value = (double) mObj.value_short; 

     color = calc_color(value, scale_for_this_type); 
    break; 

    // etc... 10+ cases 
    } 


    drawLine(last_x, last_y, x, y, color); 

    } 
} 
+2

コードを投稿できますか? – Tudor

+0

あなたの "質問"ははるかに長いです。このすべてを単純な質問に凝縮できますか? –

+0

こんにちは、私はそれを凝縮するのに少し問題がありますが、 "コードを壊さずにインナースイッチを避けるにはどうすればいいですか" – NikkyD

答えて

1

あなたのコードは非常にオブジェクト指向OKですが、ないに焦点を当てました。私はおそらく(私が命名規則を尊重するdrawGraphの名前を変更することになる)draw_graph方法に、intではなく、引き出しインターフェースのいくつかの種類を使用し、適切な実装を渡します

public interface Drawer { 
    void draw(MyObj obj, Graphics g); 
} 

...

private void drawGraph(Drawer drawer) { 
    for(int i = 0; i < amountOfValues; i++) { 
     MyObj obj = arrayList.get(i); 
     drawer.draw(obj, g); 
    } 
} 

...

class Drawer1 implements Drawer { 
    @Override 
    public void draw(MyObj obj, Graphics g) { 
     // same code as in case 1 of the switch 
    } 
} 
class Drawer2 implements Drawer { 
    @Override 
    public void draw(MyObj obj, Graphics g) { 
     // same code as in case 2 of the switch 
    } 
} 

すべての引き出しがいくつかのコードを共有している場合は、それらすべてがベースのAbstractDrawerクラスを拡張するようにします。

+0

良いアイデア。スイッチが関与するコードでは、Drawerを列挙型にすることを検討しています – user949300

+0

どうしたらそのインターフェイスがどのように動作するのか理解できません。 – NikkyD

+0

int(どのswitch文を実行するかを決める)を渡すのではなく、Drawerの適切なインスタンスを渡します。決定は同じ場所で行われます。 –

0

x、y、および値は、MyObjのプロパティです。 calc_colorは何をし、scale_for_this_typeはどこから来たのですか?その作業は、そのフィールドに基づいてMyObj内で、または大部分で実行できますか?もしそうなら、ループはmyObj.drawLineYouFigureOutTheColor(maybeAnArgumentOrTwoHere)を呼び出すことができます。どこかでlast_xとlast_yを追跡する必要があります。

+0

問題は、個々のメソッドを呼び出さないと、値を読み取るメソッドが何とか格納されていなければならないということです。提示/抽選の決定はある時点で行われなければならず、それは変数がある値を受け取る必要があり、その変数がある時点で評価される必要があることを意味します。そのポイントがループ内にあれば、パフォーマンスが低下します。それがループの前であれば、問題は最小限の混乱でコードを実行する方法です。 – NikkyD

関連する問題