Java 基于命令行参数创建子类对象的最佳方法

Java 基于命令行参数创建子类对象的最佳方法,java,oop,inheritance,factory,abstract-factory,Java,Oop,Inheritance,Factory,Abstract Factory,我有几个扩展超类的子类,我想让命令行界面用户选择使用哪个子类。所有子类都具有相同的构造函数形式 例如,我希望能够调用run--subclass=subclass 1,从而调用subclass obj=new subclass(arg1,arg2)。我可以想出几种方法来做到这一点,但我认为这种模式经常出现,以至于有一种标准或公认的方法来做到这一点;如果没有,我想做最优雅和简单的事情 下面是我当前的建议(假设有一个名称空间对象包含命令行参数): 超类createObject(命名空间, 第1类arg

我有几个扩展超类的子类,我想让命令行界面用户选择使用哪个子类。所有子类都具有相同的构造函数形式

例如,我希望能够调用
run--subclass=subclass 1
,从而调用
subclass obj=new subclass(arg1,arg2)
。我可以想出几种方法来做到这一点,但我认为这种模式经常出现,以至于有一种标准或公认的方法来做到这一点;如果没有,我想做最优雅和简单的事情

下面是我当前的建议(假设有一个
名称空间
对象包含命令行参数):

超类createObject(命名空间,
第1类arg1,
ArgumentClass2(arg2)引发异常{

Map我建议为每个子类创建一个工厂类,并将这些工厂的实例放在
类映射中。这将帮助您避免反射(性能可能更好)

超类createObject(命名空间,
第1类arg1,
ArgumentClass2(arg2)引发异常{
Map classMap=ImmutableMap.builder()
.put(“子类1”,新的子类工厂1())
.put(“子类2”,新的子类工厂2())
.build();
返回classMap.get(namespace.getString(“子类”)).newInstance(arg1,arg2);
}

PS:或者,如果每个java运行时只需要一个实例,那么这些子类工厂可以是枚举。

除了性能之外,还有其他原因可以避免反射吗?这需要更多的代码——每个子类需要一个完整的工厂类。反射往往会降低代码的可读性,并妨碍IDE理解您的代码。您应该如果可能的话,我会尽量避免反射。(但在你的具体案例中,所有这些论点并不完全一致。如果你对使用反射有更好的感觉,那为什么不呢?!)
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);
}
SuperClass createObject(Namespace namespace, 
                        ArgumentClass1 arg1, 
                        ArgumentClass2 arg2) throws Exception {
    Map<String, SubClassFactory> classMap = ImmutableMap.<String, SubClassFactory>builder()
            .put("subclass1", new SubClassFactory1())
            .put("subclass2", new SubClassFactory2())
            .build();
    return classMap.get(namespace.getString("subclass")).newInstance(arg1, arg2);
}