2015-08-16 64 views
0

SQLite和這裏Java初學者,創建從ResultSet中複雜對象

我目前工作的一個遊戲,玩家隨機獲得物品,因爲我計劃包括一個巨大的項目的數量,我已存儲的項目信息在SQLite數據庫。

事情是,我的項目對象除了像字符串名稱,詮釋權力等字段有自己的行爲對象。這使得轉換結果爲對象更復雜的努力。目前,我將這些行爲稱爲db中的Strings,然後在Item Creation中使用Switch語句實例化正確的行爲對象。這僅僅是一個半虛構的例子來說明我的意思:

Item item = new Item(); 

String name = resultSet.getString("Name"); 
String activationEffect = resultSet.getString("Activation Effect"); 

item.setName(name); 

switch (activationEffect){ 
    case "Smack Fools": 
     item.setActivationEffect(new SmackFools()); 
     break; 
    case "Have a Nap": 
     item.setActivationEffect(new NapTime()); 
     break; 
    default: 
     break; 

我也可以做item.setActivationEffect採用String,做switch語句本身,但並沒有真正改變任何東西。有沒有更好的方法來完成這一點?

+1

你應該只問每個問題一個問題。考慮到你的兩個問題是完全不同的。請刪除你的第二個。你可以就此提出另一個問題。它會幫助你得到更多更好的答案。 –

+0

好的,會做的。 – dGFisher

+0

將對象圖存儲在關係數據庫中的一種非常簡單的方法是讓您的類實現「Serializable」,然後將整個序列化對象圖存儲在數據庫列中。您可以通過將對象「串化」爲JSON String來做類似的事情,然後將字符串保存到數據庫字段中。序列化表單和JSON'String'都可以反序列化爲原始對象。必須小心謹慎,以確保序列化表格的高效性和正確性。 – scottb

回答

1

您需要一種將每個行爲名稱(一個String)與其類關聯起來(以創建該類的新對象)的方法。由於行爲名稱與類名稱不完全相同,因此不能直接使用反射。
所以沒有辦法繞過它,你必須製作一張桌子。
有很多方法可以做這樣的表,你的開關是有效的。雖然可能你不喜歡它的冗長;每個新行爲都需要三行。

在下面的代碼中,所有這些都被隔離在一個類中。
每次添加新行爲時,只需添加一行。
我假設所有行爲擴展了一個普通的ActivationEffect類,或者全部實現了一個普通的ActivationEffect接口。

class ActivationEffectsFactory { 
    private static Map<String, Class<? extends ActivationEffect>> map = new HashMap<>(); 
    static 
    { 
     add("Smack Fools", SmackFools.class); 
     add("Have a Nap", Naptime.class); 
    } 

    private static void add(String name, Class<? extends ActivationEffect> behaviour) { 
     assert !map.containsKey(name); 
     assert behaviour!=null && name!=null; 
     map.put(name, behaviour); 
    } 

    public static ActivationEffect build(String name) 
    { 
     ActivationEffect res; 
     try { 
      res = map.get(name).newInstance(); 
     } catch (InstantiationException | IllegalAccessException ex) { 
      res = null; 
     } 
     if (res==null) 
      throw new IllegalArgumentException("Incorrect behaviour name : " + name); 
     return res; 
    } 
} 

當你想添加一個新的效果,你只需要在靜態塊中這樣做。
從它的名字,你會得到正確的類的新對象:

item.setActivationEffect(ActivationEffectsFactory.build(activationEffect)); 
1

工廠格局將是對您有用:

假設你的類SmackFoolsNapTime有一個共同的超命名,例如,ActivationEffect,你要編寫一個工廠類是這樣的:

class EffectFactory 
{ 
    private final Map<String, Class> map=createMap(); 

    private Map<String, Class> createMap() 
    { 
     Map<String, Class> map=new HashMap<String, Class>(); 
     // ... Store here the allowed mappings: 
     // map.put("Smack fools", my.package.SmackFools.class); 
     // map.put("Have a nap", my.package.NapTime.class); 
     return map; 
    } 

    public ActivationEffect createActivationEffect(String name){ 
     // ... Get a Class indexing the map by name, and instantiate it. 
     // If not found, throw an exception (for example, IllegalArgumentException). 
    } 
} 

在這樣,如果您想添加ActivationEffect的新實現,則只需在createMap中添加一行即可。如果您希望它更加靈活,可以將映射存儲在.properties文件中,並修改createMap以讀取該文件。

在這種情況下,另一個附加有用的模式將實現工廠作爲

final class EffectFactory 
{ 
    private static final EffectFactory INSTANCE=new EffectFactory(); 

    public static EffectFactory getInstance() 
    { 
     return INSTANCE; 
    } 

    private EffectFactory(){} 

    // ... 
}