java 中解析控制台命令的优雅方式
Elegant way to parse console commands in java
所以我正在制作一个通过控制台命令工作的应用程序(想想 "database new db_name")。处理这种事情最优雅的方法是什么?
这是我的小原型,基本上只有大量的开关。我的意思是它可以工作,但是一旦我想添加一些东西,比如如果你传递了一个错误的参数或太少的参数,它就会变得有点混乱,所以我想知道是否有更好的选择:
public static void main(String[] args) {
while (running) {
Scanner in = new Scanner(System.in);
String cmd = in.nextLine();
parseCmd(cmd);
}
}
private static void parseCmd(String s) {
String[] cmd = s.split(" ");
try {
switch (cmd[0]) {
case "exit":
running = false;
System.out.println("Shutting down...");
break;
case "database":
switch (cmd[1]) {
case "new":
databases.add(new Database(cmd[2]));
break;
default:
System.out.println("Unknown parameter");
break;
}
break;
default:
System.out.println("Unknown command");
break;
}
} catch (Exception ArrayIndexOutOfBoundsException) {
System.out.println("Too few arguments passed");
}
}
也许你可以使用一个库来为你做很多这些命令解析,比如 joptsimple?
我不知道最优雅的方式,但我已经做过几次这样的事情并想出了这个解决方案。
为代表命令的 "database" 创建一个 class,一旦找到字符串 "database",您将检索此 class 的实例并将剩余的传递给它参数,因此它可以进行其余的解析。
class DataBaseCommand implements Command {
@Override
public void eval(String[] args) {...}
}
然后您可以将这些命令的静态映射映射到它们的名称:
private static final Map<String, Command> commands = new HashMap<>();
static {
commands.put("database", new DataBaseCommand());
}
switch (cmd[0]) {
case "exit":
running = false;
System.out.println("Shutting down...");
break;
default:
if(commands.contains(cmd[0])) {
commands.get(cmd[0]).eval(cmd);
} else {
System.out.println("Unknown command");
}
break;
}
我建议使用http://jcommander.org/。它简单而优雅。在其中您可以使用内置注释
例如使用 jcommander annotaions
创建一个像这样的 class
@Parameters(commandNames = {"test", "Manages dates"})
public class CommandOption {
@Parameter(names = {"-e", "--exit"}, description = "bla bla")
public boolean exit = false;
}
then in main method
public static void main(String... args){
CommandOption opt = new CommandOption();
JCommander jc = new JCommander(opt);
jc.parse(args);
//and now use
System.out.println("value" +opt.exit)
}
然后可以将参数作为 java class
-e true 或者如果你可以创建 jar 然后 java -jar 'jar' -e true
可能更好
所以我正在制作一个通过控制台命令工作的应用程序(想想 "database new db_name")。处理这种事情最优雅的方法是什么?
这是我的小原型,基本上只有大量的开关。我的意思是它可以工作,但是一旦我想添加一些东西,比如如果你传递了一个错误的参数或太少的参数,它就会变得有点混乱,所以我想知道是否有更好的选择:
public static void main(String[] args) {
while (running) {
Scanner in = new Scanner(System.in);
String cmd = in.nextLine();
parseCmd(cmd);
}
}
private static void parseCmd(String s) {
String[] cmd = s.split(" ");
try {
switch (cmd[0]) {
case "exit":
running = false;
System.out.println("Shutting down...");
break;
case "database":
switch (cmd[1]) {
case "new":
databases.add(new Database(cmd[2]));
break;
default:
System.out.println("Unknown parameter");
break;
}
break;
default:
System.out.println("Unknown command");
break;
}
} catch (Exception ArrayIndexOutOfBoundsException) {
System.out.println("Too few arguments passed");
}
}
也许你可以使用一个库来为你做很多这些命令解析,比如 joptsimple?
我不知道最优雅的方式,但我已经做过几次这样的事情并想出了这个解决方案。
为代表命令的 "database" 创建一个 class,一旦找到字符串 "database",您将检索此 class 的实例并将剩余的传递给它参数,因此它可以进行其余的解析。
class DataBaseCommand implements Command {
@Override
public void eval(String[] args) {...}
}
然后您可以将这些命令的静态映射映射到它们的名称:
private static final Map<String, Command> commands = new HashMap<>();
static {
commands.put("database", new DataBaseCommand());
}
switch (cmd[0]) {
case "exit":
running = false;
System.out.println("Shutting down...");
break;
default:
if(commands.contains(cmd[0])) {
commands.get(cmd[0]).eval(cmd);
} else {
System.out.println("Unknown command");
}
break;
}
我建议使用http://jcommander.org/。它简单而优雅。在其中您可以使用内置注释 例如使用 jcommander annotaions
创建一个像这样的 class@Parameters(commandNames = {"test", "Manages dates"})
public class CommandOption {
@Parameter(names = {"-e", "--exit"}, description = "bla bla")
public boolean exit = false;
}
then in main method
public static void main(String... args){
CommandOption opt = new CommandOption();
JCommander jc = new JCommander(opt);
jc.parse(args);
//and now use
System.out.println("value" +opt.exit)
}
然后可以将参数作为 java class
-e true 或者如果你可以创建 jar 然后 java -jar 'jar' -e true