2

I am in the process of refactoring a Java application that accepts commands from terminal. Currently, there is a huge if-else structure that checks for the command issued and executes the required method. I was wondering if it was possible to replace this logic with a well established design pattern. I looked at Command pattern and Strategy pattern, but cannot seem to get my head around it in this scenario. Please suggest.

Update: I do use JCommander, but that doesn't get rid of the if-else structure.

    MyCommand cmd1 = new MyCommand();
    ...
    ...
    MyCommandN cmdN = new MyCommandN();
    JCommander cmd = new JCommander();
    cmd.addCommand("myCommand1", cmd1);
    ...
    ...
    cmd.addCommand("myCommandN", cmdN);
    try {
        cmd.parse(args);
        //
        if ("myCommand1".equals(cmd.getParsedCommand())) {
           System.out.println("running command1");
        }
        ...
        ...
        else if ("myCommandN".equals(cmd.getParsedCommand())) {
            // Sysout statements only for illustration. I call command specific methods here.
            System.out.println("running commandN");
        } else {
           cmd.usage();
        }
        //
    } catch (ParameterException ex) {
        System.out.println(ex.getMessage());
        cmd.usage();
    }
trailblazer
  • 1,421
  • 5
  • 20
  • 43
  • See [Which Java Design Pattern fits best for if-else statement including loop?](https://stackoverflow.com/questions/33010710). – f_puras Oct 09 '15 at 07:42

2 Answers2

1

Use JCommander: http://jcommander.org/#Overview

There are other alternatives as well. See also: Command Line Parsing: Commons CLI alternatives?

Community
  • 1
  • 1
Kenny Ingle
  • 115
  • 6
  • May be I was not very clear earlier. I am using JCommander, but it does not help me get rid of the if-esle structure. I have added an update to the question. Please help if you know how to have a better design for this problem. – trailblazer Oct 08 '15 at 14:06
  • As an alternative to the if-else, you can use a switch on the getParsedCommand() string if you're on Java 7+ – Kenny Ingle Oct 08 '15 at 18:52
  • I know how a switch case can replace an if else. But if-else isn't the problem here. The problem is the code that is difficult to read and is not very extensible. Think of the situation where I have to support one additional command. I will have to modify the existing structure to have another else-if or a switch statement. This is an example of bad programming design. Design patterns help us to design our programs in such a way that they are more readable, loosely coupled and scalable. You might want to start reading about design patterns. The earlier, the better. – trailblazer Oct 09 '15 at 22:19
1

Introduce a common command interface and use a Map

Map<String, Command> commands = new HashMap<String, Command>();
commands.put("myCommand1", new MyCommand());
commands.put("myCommandN", new MyCommandN());

JCommander cmd = new JCommander();
cmd.addCommand("myCommand1", cmd1);
...
cmd.addCommand("myCommandN", cmdN);
try {
    cmd.parse(args);

    Command command = commands.get(cmd.getParsedCommand());
    if(command == null){
       cmd.usage();
    }
    // execute command
}
 ...
René Link
  • 48,224
  • 13
  • 108
  • 140