1

当程序从控制台获取命令时,验证命令是否有效并执行它的标准/最佳实践是什么?
我在想类似的东西,HashMap<String,Object>但这不会降低所有字符串比较的性能吗?

4

3 回答 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 回答