2011-12-10 67 views
1

我有很多類UNO,HAV,MAS,KOS 我想創建一個工廠模式。Java工廠模式 - 動態加載類

validator.load("UNO").validate(); 

我需要動態加載類到驗證器類中並返回一個實例。
(動態設置類的名稱並返回實例)
我的問題是:如果我有不兼容的類型,如何返回類的實例?

我不知道在返回類型的方法中寫什麼。

Validator CLASS中的主要問題。

public SegmentAbstract load(String str) { 

AND

return SegmentAbsClass.forName(identify); 

Main類

try{ 
    validator.load("UNO").validate(); 
}catch(Exception e){ 
    System.out.print("No class "); 
} 

抽象類(SegmentAbstract)

public abstract class SegmentAbstract { 

    public abstract Boolean validate(); 
} 

類UNO

public class UNA extends SegmentAbstract{ 

    public Boolean validate() { 
    System.out.print("UNO!!"); 
    return true; 
    } 

} 

類驗證

public class Validator { 

    public SegmentAbstract load(String str) { 
    String identify = str.substring(0, 3); 
    try { 

     return SegmentAbsClass.forName(identify); 
    } 
    catch(Exception e) { 
     return this; 
    } 

    } 
} 
+0

你是否必須總是返回一個'SegmentAbstract'類的新副本? – hellectronic

+1

@Dezigo只要你的類擴展'SegementAbstract',它們不是不兼容的,因爲它們都實現了'validate()'。究竟是什麼問題? – stacker

+0

是的!總是一個新的副本! – Dezigo

回答

1

我會做這樣的事情:

// ISegment.java 
public interface ISegment { 
    Boolean validate(); 
} 

// Uno.java 
public class Uno implements ISegment { 
    public Boolean validate() { 
     System.out.print("UNO!!"); 
     return true; 
    } 
} 

// SegmentFactory.java 
public final class SegmentFactory { 
    public static enum Supported { 
     UNO("uno", Uno.class), /* ... */, HAV("hav", Hav.class); 

     private final Class<?> clazz; 
     private final String name; 

     private Supported(final String name, final Class<?> clazz) { 
      this.name = name; 
      this.clazz = clazz; 
     } 

     public Class<?> getClazz() { 
      return clazz; 
     } 

     public static Supported for(final String name) { 
      for (final Supported s : values()) { 
       if (s.name.equals(name) { 
        return s; 
       } 
      } 
      return null; // a default one 
     } 
    } 

    public static ISegment create(final Supported supp) { 
     if (supp == null) { 
      return null; 
     } 
     return supp.getClazz.newInstance(); 
    } 

    private SegmentFactory() { 
     // avoid instantiation 
    } 
} 

用法:

final ISegment sa = SegmentFactory.create(SegmentFactory.Supported.for("uno")); 
sa.validate(); 

未測試!

2

試試這個:

public interface Validator { 
    boolean validate(Object obj); 
} 

public final class ValidatorFactory { 
    private ValidatorFactory(){} 

    public static Validator load(String type){ 
     try { 
      Class<?> clazz = Class.forName(type); 
      if (Arrays.asList(clazz.getInterfaces()).contains(Validator.class)){ 
       return (Validator) clazz.newInstance(); 
      } 
      throw new IllegalArgumentException("Provided class doesn't implement Validator interface"); 
     } catch (Exception e) { 
      throw new IllegalArgumentException("Wrong class provided", e); 
     } 
    } 
} 

也許這將幫助???

+0

謝謝,但我選擇了另一種方式。:) – Dezigo

1

看一看here。簡單地說,這個想法是在工廠類中創建一個映射(Map<String,String>,鍵是標識符,值是完全限定的類名),並在初始化期間添加受支持的類。然後使用反射來實例化工廠方法中的對象。此外,您可以通過使用Map<String, SegmentAbstract>而不是Map<String,String>並將public abstract getNewSegment()添加到您的SegmentAbstract類中來避免反思。

+0

我認爲最好使用'Map >'進行重構。 – 2011-12-10 13:16:14

+0

@RC:我同意,這只是一個例子,希望將OP推向正確的方向。 – a1ex07