我有一组使用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();
}
显然,随着可用命令列表的增加,这变得非常繁琐的代码
答案 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方法,则使用默认的构造函数)。