2011-12-11 33 views
2

我是一名Android/Java初學者,與編碼不同,但與語言相關。避免循環切換序列的故障

我的問題:

我在繪製圖形(一些統計分析)與canvas.drawLine()用不同顏色的每一行。顏色取決於數組的值。該數組(列表)包含具有大約20個不同類型變量的自定義對象。

在某些情況下,我需要一個開關來爲每個繪製調用獲取正確的類型,但對於整個循環來說,該開關具有相同的結果。當我正在完成該程序時,我正在尋找性能問題,這是一個問題。 該圖繪製了至少1000行,因此交換機運行1000次以獲得相同的結果。

如果我有數組而不是自定義對象,我可以簡單地使用int來訪問不同的數組值。但是沒有辦法重寫它,這樣就可以避免這些對象(在其他地方會讓大量代碼變得糟糕)。

現在我讀到多態性與反思,但......說實話,我不想要實現,我不完全理解的東西,這是不防彈(反射被認爲是容易出錯?!)

我目前的解決方案是我爲每個案例創建了一個自定義繪圖方法。我在循環前有一個開關,然後右邊的getter的繪圖方法正在工作。它的工作原理,但是隻有一行不同的10種方法似乎很瘋狂。

現在也有抽象類的東西,但它讓我困惑了一下,我想知道這些覆蓋的方法是否會導致比交換機更多的性能問題。我讀了一些關於java到底做了什麼的東西,並且那些跨類的方法調用可能會降低性能(我承認這是關於內部/嵌套類調用外部類的getter的東西)。

我希望代碼儘可能簡短易讀,所以我希望將它全部放在一個代碼塊中(有點),而不是分散在不同的類中,但這只是個人偏好。最重要的是,我完全理解我正在實施的是什麼。我不想要一些例子,我複製並粘貼'在這裏輸入你的方法',並看到它的工作,但不知道爲什麼或如何。

所以我其實更感興趣的是理論應該怎麼辦比實際的代碼片段(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

你的代碼是好的,但不是很面向對象的。我可能會使用某種類型的抽屜接口,並通過相應的執行,而不是一個int,到draw_graph方法(我將重新命名drawGraph尊重命名慣例):

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

好主意。由於代碼涉及開關,考慮使抽屜成爲枚舉 – user949300

+0

對不起,我不明白接口是如何工作的,在什麼時候開關/決策,繪製什麼,會發生什麼? – NikkyD

+0

而不是傳遞一個int(它決定你的switch語句將執行哪種情況),傳遞適當的Drawer實例。決定發生在同一個地方。 –

0

x,y和值是MyObj的屬性。 calc_color做了什麼,scale_for_this_type來自哪裏?這項工作是否可以在MyObj的基礎上完成,或基本上在MyObj的基礎上完成?如果是這樣,你的循環幾乎可以調用myObj.drawLineYouFigureOutTheColor(maybeAnArgumentOrTwoHere)。你必須在某處追蹤last_x和last_y。

+0

問題是,讀取值的方法必須以某種方式存儲,如果我不調用個別方法。決定展示/抽取的內容必須在某個時間點進行,這意味着變量將不得不接受某些值,並且該變量需要在某個時間點進行評估。如果這一點在循環中,它會讓我付出業績。如果它在循環之前,那麼問題是如何在代碼中使用最少的混沌。 – NikkyD