2015-08-16 2 views
0

SQLite и Java для начинающих здесь,Создания сложных объектов из ResultSet

Я в настоящее время работаю над игрой, где игрок получает случайные элементы, так как я планирую в том числе огромного количества предметов, я сохраненные информацию пункта в SQLite db.

Дело в том, что объекты моего объекта имеют свои собственные объекты поведения в дополнение к таким полям, как String name, int power и т. Д. Это делает преобразование результатов в объекты более сложным делом. В настоящее время я имею в виду эти поведения как строки в db, а затем создание экземпляра правильного объекта поведения с помощью оператора Switch в Item Creation. Это только полу-вымышленный пример, чтобы показать, что я имею в виду:

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 взять строку и сделать переключатель заявление сам, но это не меняет ничего. Есть ли лучший способ сделать это?

+1

Вы должны задать только один вопрос на каждый вопрос. Тем более, что ваши два вопроса совершенно разные. Пожалуйста, удалите свой второй. Вы можете задать еще один вопрос. Это поможет вам получить больше и больше ответов. –

+0

Хорошо, сделаю. – dGFisher

+0

Очень простой способ хранения графов объектов в реляционной базе данных состоит в том, чтобы ваши классы реализовали «Serializable», а затем сохранили весь сериализованный граф объектов в столбце базы данных. Вы можете сделать что-то подобное, «стягивая» свой объект в JSON 'String', а затем сохраняя строку в поле базы данных. Сериализованную форму и JSON 'String' можно десериализовать в исходный объект. Необходимо проявлять осторожность, чтобы ваши серийные формы были эффективными и правильными. – scottb

ответ

1

Вам нужен способ связать каждое имя поведения (a 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

завода модели будет полезна для Вас:

Предполагая, что ваши классы SmackFools и NapTime имеют общий суперкласс по имени, например, 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(){} 

    // ... 
} 
Смежные вопросы