我正在尝试找到最佳解决方案,使我的Java应用程序可以通过命令行进行配置。我面临的问题是我需要配置复杂的嵌套结构。
考虑以下结构(以大写字母开头的单词,缩进表示属性)
我需要从命令行中选择的第一件事是实现InterfaceOptimizer
的类(例如java App -O SomeOptimizer
)。接下来要选择的是AbstractProblem
,它本身会采用另一个参数dimension
(例如java App -O SomeOptimizer -- -P ConcreteProblem
。
这里的问题是某些参数是特定类的参数,并取决于首先给出的参数。 ConcreteProblem可能采用与OtherProblem不同的参数。
我测试了args4j和commons-cli,但是在尝试做我需要的时候都失败了。
WEKA(一种流行的机器学习工具)似乎已经针对这个问题实现了a solution,但它基本上要求每个类实现它自己的CLI解析器(并且它们似乎存在一致性问题)。
这个问题有没有好的解决方案(现有的库?)?建议的模式是什么来解决这个问题?
答案 0 :(得分:1)
我认为你可能只需编写选择正确类的代码。之后,您可以使用反射将值放入对象和/或验证命令行选项是否合适。注释会在这里帮助你,因为你可以使用它来帮助驱动反射引擎,以及生成文档,例如命令行帮助。
答案 1 :(得分:0)
只是一个想法,但这看起来很像将对象图反序列化给我。 Java具有内置的对象序列化/反序列化。例如。从XML文件构造一个对象:
FileInputStream is = new FileInputStream(new File("config.xml"));
XMLDecoder d = new XMLDecoder(is);
InterfaceOptimizer obj = (InterfaceOptimizer)d.readObject();
要获取初始配置文件(作为可手动更改的起点),可以通过编程方式创建对象,然后使用以下命令将其转储到XML文件:
FileOutputStream os = new FileOutputStream(new File("config.xml"));
XMLEncoder e = new XMLEncoder(os);
e.writeObject(myOptimizerObject);
然后,您必须只在命令行上传递配置文件。
答案 2 :(得分:0)
我不知道这个CLI是如何复杂的,除非我不完全理解。你想要
java X classname problem dimension population numberruns
现在,即使是部分
classname problem dimension
或只是
problem dimension
可以重复,很容易:
classname problem dimension
。代码(待完善):
try {
IOptimizer io = (IOptimizer) Class.forName(args[n]).newInstance();
io.init(args[n+1], args[n+2]);
}
catch (ClassNotFoundException ...) { ... }
catch (ClassCastException ...) { ... }
catch (InvalidArgumentException ...) { ... }
请注意,如果某些问题需要多个参数,您可以这样执行:
java X classname problem3 a,b,c population numbers
然后你可以在init()方法中拆分维度参数。