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语句本身,但这并没有真正改变任何东西。有没有更好的方法来实现这一目标?
答案 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 模式对您有用:
假设您的类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
以读取该文件。
在这种情况下,另一个有用的模式是将工厂实现为 singleton :
final class EffectFactory
{
private static final EffectFactory INSTANCE=new EffectFactory();
public static EffectFactory getInstance()
{
return INSTANCE;
}
private EffectFactory(){}
// ...
}