スーパークラスを拡張するいくつかのサブクラスがあり、コマンド ライン インターフェイスのユーザーが使用するサブクラスを選択できるようにしたいと考えています。すべてのサブクラスは同じコンストラクタ形式を持ちます。
たとえば、 を呼び出せるようにしたいのですが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);
}
サブクラスのコンストラクターがすべて引数を取らない場合、これは a を使用せず、Constructor
を実行することで簡素化できますreturn classMap.get(namespace.get("subclass")).newInstance();
。1 つの欠点は、ここまたは上流で処理する必要があるいくつかの例外 ( InstantiationException
、IllegalAccessException
、NoSuchMethodException
、 ) のいずれかをスローする可能性があることに注意してください。InvocationTargetException
これは合理的ですか?それは最善の方法ですか?使用する標準パターンはありますか?