![](/img/trans.png)
[英]Better way to instantiate child classes with shared interface/baseclass
[英]Better way to instantiate multiple different classes in Java via factories
假設您有很多類似的類可能隨時被實例化。 一個明顯的寫法是使用大量的條件句:
public static Common factory(String key, InstantiationObj instantiationObj) {
if( key == "A") {
return new TypeA(instantiationObj);
}
else if( key == "B") {
return new TypeB(instantiationObj);
}
else if( key == "C" ) {
return new TypeC(instantiationObj);
}
else if( key == "D" ) {
return new TypeD(instantiationObj);
}
else {
return new DefaultClass(instantiationObj);
}
}
我喜歡避免所有的條件。 在 Java 我得到了這個工作:
public static <T extends Common> T factory(String key, InstantiationObj instantiationObj) throws Exception {
Class[] cArg = new Class[1];
cArg[0] = InstantiationObj.class;
HashMap<String, Class> potentialClasses = new HashMap<>();
potentialClasses.put("A", TypeA.class);
potentialClasses.put("B", TypeB.class);
potentialClasses.put("C", TypeC.class);
potentialClasses.put("D", TypeD.class);
Class<T> classType = potentialClasses.getOrDefault(key, DefaultClass.class);
return classType.getDeclaredConstructor(cArg).newInstance(instantiationObj);
}
這更容易測試,但在我看來仍然很笨拙,尤其是確定正確構造函數的塊。 Java 是否有更精簡的方式來執行此模式?
一個建議可以是
public class CommonClass {
private static HashMap<String, Class> potentialClasses = new HashMap<>();
static {
potentialClasses.put("A", TypeA.class);
potentialClasses.put("B", TypeB.class);
potentialClasses.put("C", TypeC.class);
potentialClasses.put("D", TypeD.class);
}
public static <T extends Common> T factory(String key) throws Exception {
Class[] cArg = new Class[1];
cArg[0] = NecessaryConstructor.class;
Class<T> classType = potentialClasses.getOrDefault(key, DefaultClass.class);
return classType.getDeclaredConstructor(cArg).newInstance(descriptor);
}
我喜歡實現工廠模式的一種方法是使用 spring。 您可以在項目中擁有盡可能多的特定類型的類。
然后,在 class 中注入或自動連接相同類型的列表,Spring 將在列表中設置該類型的所有實例。
最后,將列表轉換為 map,就像您擁有的那樣,您將在您的工廠和項目中最大限度地實現“關閉修改,打開可擴展”的想法。
如果邏輯像您的情況一樣簡單,您可以使用反射,而不定義映射:
public static Common factory(String key, InstantiationObj instantiationObj) {
String className = "Type" + key;
Class<T> classType = Class.forName(className);
...
因此,對於鍵“A”,變量className將具有值“TypeA”,對於鍵“B”,它將具有值“TypeB”,等等。
但這僅適用於這種簡單的情況,當參數鍵映射到 class 名稱遵循簡單模式時。
如果以后邏輯變得更復雜,則每個條件都需要if (...)
子句。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.