当程序从控制台获取命令时,验证命令是否有效并执行它的标准/最佳实践是什么?
我在想像HashMap<String,Object>
这样的东西,但这不会降低所有字符串比较的性能吗?
答案 0 :(得分:2)
首先,不要担心性能。时间会更晚(或者更有可能,根本不会发生)。解析命令不会比执行命令花费更多时间,是吗?
至于处理命令:首先,您应该将输入拆分为原子令牌。这些可能是命令本身,开关-a -b -c或参数值,有时可能介于“”之间。
将输入拆分为令牌后,请验证命令是否存在。如果是,请检查令牌供应是否对命令有效。
我不知道您想要使用哪种架构。有时候人们会将一个类用于一个命令,有时会有一个类和很多方法,有时会有一个方法具有极长的情况。哪个最适合你?可能不是最后一个,但无论你选择什么都应该与命令及其工作的复杂性相匹配。
例1:
abstract class Command {
public abstract String getName();
public abstract int execute(String[] parameters); // not implemented in Cmd* below
}
class Cmd1 extends Command {
public String getName()
{
return "Cmd1";
}
}
class Cmd2 extends Command {
public String getName()
{
return "Cmd2";
}
}
//somewhere else:
public void execute(String[] params) {
Command[] commands = {new Cmd1(), new Cmd2()};
for (Command cmd: commands) {
if (cmd.getName().equals(params[0]) {
cmd.execute(params);
return;
}
}
throw new RuntimeException("unknown command "+params[0]);
}
示例2:
void processCmd1(String[] params);
void processCmd2(String[] params);
public static final String CMD1 = "cmd1";
public static final String CMD2 = "cmd2";
static HashSet<String> availableCommands = new HashSet<String>();
static {
availableCommands.put(CMD1);
availableCommands.put(CMD2);
}
{
if (availableCommands.contains(params[0])) {
switch(params[0]) { // java 7
case CMD1:
processCmd1(params[0]);
break;
case CMD2:
processCmd2(params[0]);
break;
}
} else {
throw new RuntimeException("unknown command "+params[0]);
}
}
示例3:
abstract class Command {
public abstract String getName();
public abstract int execute(String[] parameters); // not implemented in Cmd* below
}
class Cmd1 extends Command {
public String getName()
{
return "Cmd1";
}
}
class Cmd2 extends Command {
public String getName()
{
return "Cmd2";
}
}
static HashMap<String,Command> commandMap = new HashMap<String,Command>();
static {
Command cmd = new Cmd1();
commandMap.put(cmd.getName(), cmd);
cmd = new Cmd2();
commandMap.put(cmd.getName(), cmd);
}
//somewhere else:
public void execute(String[] params) {
Command cmd = commandMap.get(params[0]);
if (cmd == null) {
throw new RuntimeException("unknown command "+params[0]);
} else {
cmd.execute(params);
}
}
答案 1 :(得分:0)
有一个很好的库用于命令行参数处理。它是Apache commons CLI。
答案 2 :(得分:0)
标准的设计模式是责任链或口译员,但口译员可能过度。责任链基本上是一种动态创建if / then / else决策树的方法,而不是将其硬编码为/ then / else语句。
我会预处理输入,然后使用Chain of Responsibility来解析输入。
我很确定命令行parg处理的标准库使用编译成运行代码的正式语法。至少那是我在上次使用它时的石器时代的回归(lex和yacc是受欢迎的选择),但今天它可能很特别。