2016-05-18 50 views
4

我有一個類(活動)在一個Android應用程序,它有一堆示例數學問題。您可以通過按下更改問題計數器並顯示新問題的按鈕來轉到其他問題。您可以通過單擊「顯示工作」按鈕來查看如何解決問題,該按鈕會在屏幕上顯示一堆信息。我的問題是我有一堆看起來像這樣的方法:在java中將行爲存儲爲數據的最佳方式是什麼?

public void showWorkButtonClicked() 
{ 
    if (questionCounter == 1) 
     showWork1(); 
    else if (questionCounter == 2) 
     showWork2(); 
    else if (questionCounter == 3) 
     showWork3(); 
    //for how ever many questions are available 
} 

很明顯,這些if語句是可怕的設計。我可以將每個函數所需的數據存儲在一個類中,這可能在這種情況下起作用(但可能會讓事情變得混亂),但是如果每個showWork方法都足夠獨特,那麼這會不切實際。我知道如果我使用C#製作應用程序,我可以簡單地將代表放入列表中,並且會有一個優雅的解決方案。如果有人有更好的解決方案(理想情況下使用更少的代碼),我很樂意聽到它。

+0

在Java中查看函子[幫助理解Java中的函數對象或函子](http://stackoverflow.com/questions/7369460/help-with-understanding-a-function-object-or-functor-in- java)以及幻燈片包[函數和命令模式](http://www.buyya.com/254/Patterns/Command-2pp.pdf)的PDF文件。另請參閱https://www.cs.odu.edu/~zeil/cs330/f15zeil/Public/functors/index.html –

回答

4

使用Map<Integer, Runnable>來存儲你的行動:

private static Map<Integer, Runnable> actions = new HashMap<Integer, Runnable>() {{ 
    put(1,() -> showWork1()); 
    put(2,() -> showWork2()); 
    put(3,() -> showWork3()); 
}}; 

然後看看他們:

public void showWorkButtonClicked() { 
    actions.getOrDefault(questionCounter,() -> {}).run(); 
} 

這裏我用一個「什麼都不做」可運行,以避免NPE,如果有一個不採取行動數。或者,您可以:

public void showWorkButtonClicked() { 
    Optional.of(questionCounter) 
     .map(actions::get) 
     .orElseThrow(IllegalArgumentException::new) 
     .run(); 
} 
+0

如果這些「int」值構成連續範圍,則「Runnable []」數組將作爲好。使用數組的優點是,您可以使用大括號語法來真正地初始化它,而不是使用*混淆的匿名內部類*反模式。 – Holger

+0

@Holger這不是一個內部類。這是一個*靜態*內部類 - 差別很大,因爲只有一個實例。它不是混淆(很明顯),或反模式(它很好)。並且數組不解決一般情況,即從任何數字映射(連續整數是邊緣情況)。 – Bohemian

+0

這是一個過時的附加類,無論是否爲'static'。創建一個多餘的附加類只是爲了保存幾個字符*是一種反模式。與「偏好構成而不是繼承」的建議明顯矛盾。當您仔細地放置花括號使其看起來不同於嵌套初始化程序的嵌套類時,它會被混淆。 – Holger

0

你不應該把任何數據在你的代碼,也不應該使用專門的函數來顯示不同的東西。如果要根據計數器顯示數據,請使用List或Map來存儲它,並將其讀取到單個函數中進行顯示。

相關問題