使用命令设计模式将命令行参数转换为对象

时间:2012-04-12 12:06:11

标签: java command design-patterns

我有一组使用command design pattern的对象,即它们实现了一个抽象的Command类,并且有一个execute()方法。

当从命令行调用(例如)时,您可以执行类似这样的操作,但是它非常笨重,您将如何实现:

public void main(String[] arg) {
    Command c = null;

    if(arg[0].equals("FirstCommand") {
        c = new FirstCommand(arg[1]);
    }
    if(arg[0].equals("SecondCommand") {
        c = new SecondCommand(arg[1], arg[2]);
    }
    if(arg[0].equals("ThirdCommand") {
        c = new ThirdCommand(arg[1], Long.parseLong(arg[2]));
    }
    //.....etc....
    c.execute();
}

显然,随着可用命令列表的增加,这变得非常繁琐的代码

2 个答案:

答案 0 :(得分:1)

反思很容易。从这开始:

final Class[] argTypes = new Class[args.length - 1];
final String[] cmdArgs = new String[args.length - 1];
for (int i = 0; i < argTypes.length; i++) {
  argTypes[i] = String.class;
  cmdArgs[i] = args[i+1];
}
final Command c = (Command) Class.forName(MY_PACKAGE + args[0]).getConstructor(argTypes)
   .newInstance(cmdArgs);

现在,唯一需要解决的问题是您必须将解析和验证推送到Command构造函数中。或者,如果你想获得幻想,你可以只找到一个基于arg计数的构造函数,查看它接受的arg类型,并适当地解析cmdline args。

答案 1 :(得分:0)

不要求您跟踪可用命令的通用解决方案是使用反射来实例化命令。您可以使用构造函数获取参数列表,也可以定义像McDowell建议的执行方法。这取决于您是否希望使用相同的参数多次重新执行相同的命令,以及命令是否可以从缓存结果(无状态与有状态)中受益。

命令名称将是类的简单名称。你只需添加包来创建一个完全限定的名称,然后添加class.getConstructor(Class [] params)并调用该构造函数(如果你选择将参数传递给execute方法,则使用默认的构造函数)。