2

This question is in regards to handling continuous user input in a command-line application in Java.

Within Main, I have the following code:

    Scanner sc = new Scanner(System.in);

    while(sc.hasNextLine()) {

        String line = sc.nextLine().replaceAll("\n", "");

        // return pressed
        if (line.length() == 0) {
            continue;
        }

        // split line into arguments
        String[] args1 = line.split(" ");

        // process arguments
        if (args1.length > 0) {
            if (args1[0].equalsIgnoreCase("q")) {
                System.exit(0);
            } else if (args1[0].equalsIgnoreCase("someInput")) {
                // Put stuff here
            } else {
                System.out.println("exiting");
                System.exit(0);
            }
        }
    }

As you can tell, this is to handle continuous inputs from the command-line. The program quits if the input is q, and does other stuff when it's someInput. This program is essentially a state machine.

However, this program can get messy very very quick, since it will evolve into a bunch of if-statements and boolean flags to get into the if statements.

For example, as I programmed my current CLI application, it descended into 15+ if-statements, and it's a total MESS in terms of readability and maintainability.

My question is - what is the better way to handle continuous conditional user-input without using a mess of if-statements so it's more readable and maintainable?

Note: The inputs are non-discrete, meaning, it isn't simple string matching.

5
  • Maybe set up a "Handler" or "Command" class which you can add to a List. This way, you would ask each "Command" if it was able to process the "input" and if it can, pass it to that "Command" for further processing... Commented Jun 6, 2015 at 1:24
  • 2
    If you have a discrete set of ommands in place of "someInput" put the handlers in a map. Commented Jun 6, 2015 at 1:36
  • Exactly, redge. The inputs are non-discrete, meaning, they're not pre-defined commands. Imagine writing the vim application, there are not a discrete set of inputs, but a mess of different inputs. A state machine will get exponentially complicated if that were the way it was written. Commented Jun 6, 2015 at 1:37
  • Even vim has a discrete set of commands then each command has a different structure for its arguments. A map of handlers can be used to do the first level and then if a handler needs to have a different structure to handle its variants that is a separate problem. Unless you are trying to do an artificially intelligent natural language command interpreter I suggest you have a discrete set of commands. Commented Jun 6, 2015 at 1:41
  • 1
    I would suggest that your title is wrong. This is not so much about continuous input as it it about complex command structure Commented Jun 6, 2015 at 1:44

1 Answer 1

3

Assuming your input starts with a command token, you can create a Command interface and build a map lookup. For example:

interface Command {
  void invoke(String input);
}

Then convert your if statements into Command implementation, eg:

public class CookCommand impements Command {
  void invoke(String input) {
    ..
  }
}

public class ShowerCommand implements Command {
  void invoke(String input) {
    ..
  }
}

Then build a map with these commands objects:

Map<String, Command> commands = new HashMap<>();
commands.put("shower", new ShowerCommand());
commands.put("cook", new CookCommand());

Then on your eval loop just lookup this map to get associated Command object and invoke it

Command cmd = commands.get(commandName);
if(cmd != null) cmd.invoke(input);
else System.err.println("Unknown command " + cmd);
Sign up to request clarification or add additional context in comments.

3 Comments

Hi gerry. What happens if the command isn't a discrete command?
@theGreenCabbage you really need to explain what your command structure is and why it is not discrete as noone will be able to suggest a sensible solution otherwise.
Hi @redge. Apologies. I'll post a sample snippet of my code tomorrow and give you guys a better example of what I am talking about, and you guys give me feedback on how it can be done better. Thanks for your participation in particular redge

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.