所以基本上这个标题听起来比实际问题还要好看。
我正在编写一个应用程序,我希望在其中实现一个成就系统。如果我将所有成就创建为泛型类的实例,那么当完成的专长类型可能会有所不同时,如何编写一个方法来验证这些成就(即确定用户是否达到或超过目标),条件数量要满足可能会有所不同,验证的类型可能会有所不同?
例如:
成就 - 10,000点!
类型 - 点总数
值(X) - 10,000
条件 - 1
验证 - 大于X
VS
成就 - Ultra-frag
类型 - 杀戮
价值(X) - 10
类型 - 时间
值(Y) - 10秒
条件 - 2
验证 - 至少X小于Y
我试图避免为每个成就编写验证函数的硬编码,因为它们主要是通用的,唯一的区别是它们的验证方式。
就像成就课看起来像
public class Achievement
{
boolean locked;
String name;
String desc;
public Achievement(string n, string d)
{
//ctor code
}
}
我试图想办法在没有函数指针的情况下做到这一点而且我失败了。另外,你甚至可以在java中使用函数指针吗?我是语言新手:(
答案 0 :(得分:2)
我认为正确的方法是为每个成就提供验证方法:
public abstract class Achievement {
//...name, etc
public boolean isSatisfied(Data byPlayerData);
}
但这并不能阻止您提供一些具体的实现并使用参数进行配置。
public class ZombieKillingAchievement extends Achievement {
private final int numKills;
public ZombieKillingAchievement(String name, int numKills) {
this.numKills = numKills;
}
public boolean isSatisfied(Data userData) {
return userData.getZombieKills() >= numKills;
}
}
//...
registerAchievement(new ZombieKillingAchievement("Zombie Master", 100));
registerAchievement(new ZombieKillingAchievement("Zombie Tamer", 50));
//... on user data change
for ( Achievement a : registeredAchievements ) {
if ( a.isSatisfied() ) {
//show congratulatory message
}
}
编辑防止继承(和使用合成)的另一个选择是使用类似于strategy pattern的内容。
public class Achievement {
//...name, etc
private final AchievementValidator validator;
}
public interface AchievementValidator {
public boolean isSatisfied(Data userData);
}
当与匿名内部类一起使用时,它几乎使用函数指针
registerAchievement(new Achievement("Zombie Killer", new AchievementValidator() {
public boolean isSatisfied(Data data) { return data.getZombieKills() >= 50; }
});
答案 1 :(得分:1)
Java中的函数指针(通常在任何面向对象语言中)通常由多态对象替换。
关于没有硬编码验证,我认为为此编写规则引擎是不值得的,努力会更高。你可以做的是将同一类型的成就与具有不同阈值的字段统一为同一类的对象。