簡體   English   中英

通過工廠在 Java 中實例化多個不同類的更好方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM