当程序从控制台获取命令时,验证命令是否有效并执行它的标准/最佳实践是什么?
我在想类似的东西,HashMap<String,Object>
但这不会降低所有字符串比较的性能吗?
问问题
841 次
3 回答
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);
}
}
于 2013-01-15T08:08:30.617 回答
0
对此的标准设计模式是责任链或解释器,但解释器可能是矫枉过正。责任链基本上是一种动态创建 if/then/else 决策树的方法,而不是将其硬编码为 if/then/else 语句。
我会预处理输入,然后使用责任链来解析输入。
我很确定用于命令行 parg 处理的标准库使用编译成运行代码的正式语法。至少在我上次使用它时,它在石器时代是这样完成的(lex 和 yacc 是流行的选择),但今天它可能已经很专业了。
于 2013-01-15T10:04:59.857 回答
0
有一个很好的命令行参数处理库。它是Apache commons CLI。
于 2013-01-15T08:08:05.593 回答