Mark
Mark

Reputation: 41

What is the best way to store actions as data in java?

I have a class (Activity) in an android application that has a bunch of example math problems on it. You can move to a different question by pressing a button which changes a question counter and displays a new question. You can see how to solve a question by clicking a 'show work' button, which displays a bunch of information on the screen. My problem is I have a bunch of methods that look like this:

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

Obviously these if-statement are terrible design. I could store the data needed for each function in a class, which might work in this case (but would probably just make things confusing), but what if each showWork method was sufficiently unique to make this impractical. I know if I was making the app in C#, I could simply put delegates into a list and would have an elegant solution. If anybody has a better solution (that ideally uses less code), I would love to hear it.

Upvotes: 4

Views: 312

Answers (2)

Thomas
Thomas

Reputation: 1732

You should not put any data in your code nor you should use dedicated functions to display something different. If you want to display data depending on a counter use a List or a Map to store it and read it in a single function for display.

Upvotes: 0

Bohemian
Bohemian

Reputation: 425198

Use a Map<Integer, Runnable> to store your actions:

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

then look them up:

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

Here I use a "do nothing" runnable to avoid an NPE if there's no action for a number. Alternatively, you could:

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

Upvotes: 4

Related Questions