我有几个扩展超类的子类,我想让命令行界面用户选择要使用的子类。所有子类都具有相同的构造函数形式。
例如,我希望能够调用run --subclass=Subclass1
,从而调用Subclass obj = new Subclass(arg1, arg2)
。我可以想到几种方法来做到这一点,但我认为这种模式经常出现,以至于有一种标准或公认的方法来做到这一点;如果没有,我想做最优雅和最简单的事情。
这是我目前的建议(假设有一个Namespace
包含命令行参数的对象):
SuperClass createObject(Namespace namespace,
ArgumentClass1 arg1,
ArgumentClass2 arg2) throws Exception {
Map<String, Class<? extends SuperClass>> classMap =
ImmutableMap.<String, Class<? extends SuperClass>>builder()
.put("subclass1", SubClass1.class)
.put("subclass2", SubClass2.class)
.build();
Constructor<? extends SuperClass> constructor =
classMap.get(namespace.getString("subclass"))
.getConstructor(ArgumentClass1.class, ArgumentClass2.class);
return constructor.newInstance(arg1, arg2);
}
当子类构造函数都没有参数时,这可以通过不使用 aConstructor
和doing来简化return classMap.get(namespace.get("subclass")).newInstance();
。请注意,一个缺点是这可能会引发需要在此处或上游处理的几个异常( InstantiationException
, IllegalAccessException
, NoSuchMethodException
, )之一。InvocationTargetException
这合理吗?这是最好的方法吗?有标准模式可以使用吗?