1

I want to make a simple interative shell based on the console where I can write commands like login, help, et cetera.

I first thought of using Enums, but then I didn't know how to implement them neatly without a load of if-else statements, so I decided to go with an array-approach and came up with this:

public class Parser {
    private static String[] opts = new String[] {"opt0", "opt1", "opt2", "opt3" ... }

    public void parse(String text) {
        for(int i = 0; i < opts.length; i++) {
            if(text.matches(opts[i]) {
                switch(i) {
                    case 0:
                        // Do something

                    case 1:
                        // Do something-something

                    case 2:
                        // Do something else
                }

             return;
            }
        }
    }
}

But I ended up seeing that this was probably the most rudimentary way of doing something like this, and that there would be problems if I wanted to change the order of the options. How could I make a simpler parser? This way it would work, but it would also have said problems. The use of the program is purely educational, not intended for any serious thing.

4
  • The typical "use a library" response not what you're looking for? commons.apache.org/proper/commons-cli Commented Mar 1, 2013 at 22:57
  • Nope, I'm trying to work something of my own. It's purely to learn something new. Commented Mar 1, 2013 at 22:59
  • 1
    Check Command design pattern Commented Mar 1, 2013 at 23:05
  • @jlordo Sorry, I wrote the code while I was creating the question, I didn't validate it with an IDE or anything similar. Still, I think you get the idea. Commented Mar 1, 2013 at 23:08

2 Answers 2

1

A simple approach is to have a HashMap with the key equal to the command text and the value is an instance of class that handle this command. Assuming that the command handler class does not take arguments (but you can easily extend this) you can just use a Runnable instance.

Example code:

Runnable helpHandler = new Runnable() {
    public void run(){
       // handle the command
    } 
}

// Define all your command handlers

HashMap<String, Runnable> commandsMap = new HashMap<>(); // Java 7 syntax

commandsMap.put("help",helpHandler);
// Add all your command handlers instances

String cmd; // read the user input
Runnable handler;
if((handler = commandsMap.get(cmd)) != null) {
  handler.run();
}

You can easily extend this approach to accept argument by implementing your own interface and subclass it. It is good to use variable arguments if you know the data type e.g. void execute(String ... args)

Sign up to request clarification or add additional context in comments.

3 Comments

How do you create the helpHandler? I know Runnable is an interface with a run method, but how did you declare helpHandler as Runnable, then initialised it, and then implemented the methods? I know you can create a class which implements Runnable then be able to create it and add them to the map with a cast but...
This called anonymous class in Java. It is basically as if you create a class (with no name) that implements Runnable and then you create an instance of that class. So in reality this code does not create instance of Runnable but it creats an instance of anonymous class that implements Runnable
Finally managed to achieve it. I ended up creating a static HashMap in a Shell class, with a static {...} field where I end up adding every key-value set. Thanks a lot! :)
0

One solution that comes to mind is actually using Design patterns. You could use the input from the user, as the discriminator for a Factory class.

This factory class will generate an object, with an "execute" method, based on the input. This is called a Command object.

Then you can simply call the method of the object returned from the factory.

No need for a switch statement. If the object is null, then you know the user entered an invalid option, and it abstracts the decision logic away from your input parser.

Hopefully this will help :)

2 Comments

This design pattern is very similar to one I was taught two or three weeks ago, the Facade pattern. Will read and try some things, see if I can get something working. Thanks. :)
My pleasure. If this suggestion proves useful, be sure to mark it as the correct answer :)

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.