从ResultSet创建复杂对象

时间:2015-08-16 21:16:10

标签: java sqlite jdbc

SQLite和Java初学者,

我正在开发一款玩家获取随机物品的游戏,因为我计划包含大量物品,我已将物品信息存储在SQLite数据库中。

事实上,除了String name,int power等字段之外,我的item对象还有自己的行为对象。这使得将结果转换为对象变得更加复杂。目前我将这些行为称为db中的字符串,然后使用Item Creation中的Switch语句实例化正确的行为对象。这只是一个半虚构的例子来说明我的意思:

var myApp = new function() { }

myApp.childObject1 = new function() {

    this.func= function() {
        console.log('hello');
    }
}

myApp.childObject2 = new function() {

    this.func= function() {
        console.log('world');
    }
}

myApp.childObject1.func();
myApp.childObject2.func();

或者我可以使item.setActivationEffect获取一个String并执行switch语句本身,但这并没有真正改变任何东西。有没有更好的方法来实现这一目标?

2 个答案:

答案 0 :(得分: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 :(得分:1)

factory 模式对您有用:

假设您的类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以读取该文件。

在这种情况下,另一个有用的模式是将工厂实现为 singleton

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

    public static EffectFactory getInstance()
    {
        return INSTANCE;
    }

    private EffectFactory(){}

    // ...
}