泛型类的动态验证有哪些方法?

发布于 2024-09-15 10:51:02 字数 695 浏览 6 评论 0原文

所以基本上标题听起来比实际问题更花哨。

我正在编写一个应用程序,我想在其中实现一个成就系统。如果我将所有成就创建为通用类的实例,当完成的壮举类型、条件数量可能不同时,如何编写一个方法来验证这些成就(即确定用户是否达到或超过目标)要满足的要求可能会有所不同,并且验证的类型可能会有所不同?

例如:

成就 - 10,000 点!
类型 - 总分
值 (X) - 10,000
条件 - 1
验证 - 大于 X

成就 - 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中使用函数指针吗?我对这门语言很陌生:(

So basically the title sounds way fancier than the actual question.

I am writing an application in which I would like to implement an achievement system. If I have all of my achievements created as instances of a generic class, how do I write a method to validate those achievements (i.e. determine if the user has met or exceeded goals) when the type of feat accomplished may vary, the number of conditions to be met may vary and the type of validation may vary?

For example:

Achievement - 10,000 points!
Type - point total
Value (X) - 10,000
Conditions - 1
Validation - greater than X

vs.

Achievement - Ultra-frag
Type - kills
Value (X) - 10
Type - time
Value (Y) - 10 seconds
Conditions - 2
Validation - at least X in less than Y

I am trying to avoid hardcoding a validation function for every achievement since they are mainly generic and the only difference is how they are validated.

Like the achievement class looks something like

public class Achievement 
{
    boolean locked;
    String name;
    String desc;

    public Achievement(string n, string d)
    {
        //ctor code
    }
}

I am trying to think of a way to do this without function pointers and I am failing miserably. Also, can you even use function pointers in java? Im new to the language :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝礼 2024-09-22 10:51:02

我认为正确的做法是为每个成就提供一个验证方法:

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
    }
}

编辑 防止继承(并使用组合)的另一个选项是使用类似于 策略模式

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; }
});

I think the right track would be to have a validate method for each Achievement:

public abstract class Achievement {
    //...name, etc
    public boolean isSatisfied(Data byPlayerData);
}

But that doesn't stop you from providing a few concrete implementations and configuring them with parameters.

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
    }
}

EDIT Another option to prevent inheritance (and use composition) is to use is something similar to the strategy pattern.

public class Achievement {
    //...name, etc
    private final AchievementValidator validator;
}

public interface AchievementValidator {
    public boolean isSatisfied(Data userData);
}

When used with anonymous inner classes it's pretty much using function pointers

registerAchievement(new Achievement("Zombie Killer", new AchievementValidator() {
    public boolean isSatisfied(Data data) { return data.getZombieKills() >= 50; }
});
他不在意 2024-09-22 10:51:02

Java 中的函数指针(通常在任何面向对象语言中)通常被多态对象替换。

关于不对验证进行硬编码,我认为不值得为此编写规则引擎,工作量会更高。您可以做的是将相同类型的成就统一为具有不同阈值的字段的同一类对象。

Function pointers in Java (and in general in any Object Oriented Language) are usually replaced by Polymorphic objects.

About not hardcoding the validation, I don't think it's worth to write a rule-engine for that, the effort would be much higher. What you can do is to unify the achievements of the same type as objects of the same class with a field having different thresholds values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文