2010-06-24 119 views
2

比方說,我有很多相似的類(單位在這個例子中RTS), 也就是類Unit和子類UnitAUnitBUnitCJava反射不良模式?

的單元類都具有下面的構造(包括單元)包含參數

public class UnitX { 
    public UnitX(FileReader fr) { 
     ...read parameters for constructing the unit... 
    } 
} 

我的文件具有形式

UnitX params 
UnitY params 
.... 

和創建文件中的所有單位的名單將是一個while循環一樣

Class[] params = {FileReader.class}; 
while(fr has more to read) { 
    String unitType = fr.getString(); 
    Unit u = (Unit) 
java.lang.reflect.Constructor constr = Class.forName(unitType).getConstructor(params); 
    Unit u = (Unit)constr.newInstance(new Object[]{fr}); 
    list.add(u); 
} 

我意識到,當我創建的文件對象我使用這個模式非常頻繁。 我的問題是,這是一種壞模式?有一個更好的方法嗎?

回答

2

代碼本身很好。由於構造函數不能成爲傳統編譯界面的一部分,所以下一個最好的事情就是一致的反射界面。

但是,如果您在很多地方重複此代碼,那就不太好了。您可以嘗試將它集中到某種工廠或構建器中,該工廠或構建器從文件中提供單元名稱以及爲該單元定義的參數,並將其與處理器實現配對,該處理器實例使用通過UnitFactory提供的參數實例化單元。 UnitFactory使用反射來實例化已命名的單元併爲其提供參數。

這允許重用,並從實例化中解讀文件以及實例化方法。

+0

單元類本身是否提供 讀取/寫入文件讀取器/寫入器狀態的方法更合理嗎? 額外的單元類不需要在我的工廠類中進行更改。 – 2010-06-25 19:22:45

+0

是的,這也是可能的,只要意識到你在混合責任人,但只要你意識到這一點,它可能意味着什麼就可以了。單元測試通常是故意簡單的,所以更直接的耦合方法通常是最合適的,因爲它更清晰。 – mdma 2010-06-25 19:49:39

0

這是一個簡單的,減少序列化。如果它適合你的目的,我會說這很好。

1

我認爲你的實施是好的。另一種方法:文本文件是DSL(域特定語言)的簡單形式

您可以切換到更加動態的jvm兼容語言。 Groovy(我最喜歡的;-)),javascript(Rhino,...),BeanShell,jython等動態語言可以更容易地用於實現域特定語言(DSL)。對於更復雜的DSL,您可以看看Eclipse XText項目。

3

,對於factory pattern的情況下:

java.lang.reflect.Constructor constr = Class.forName(unitType).getConstructor(params); 
Unit u = (Unit)constr.newInstance(new Object[]{fr}); 

可以的if/else雖然變成

Unit u = UnitFactory.create(unitType, fr); 

工廠隨後的列表。