Каковы некоторые методы динамической проверки для универсального класса? - PullRequest
1 голос
/ 24 августа 2010

Так что, в основном, название звучит намного причудливее, чем реальный вопрос.

Я пишу приложение, в котором я хотел бы внедрить систему достижений.Если все мои достижения созданы как экземпляры универсального класса, как мне написать метод для проверки этих достижений (т. Е. Определить, достиг ли пользователь целей или превысил их), когда тип достигнутого навыка может различаться, количество условийсоответствие может отличаться и тип проверки может отличаться?

Например:

Достижение - 10000 баллов!
Тип - общее количество баллов
Значение (X) - 10000
Условия - 1
Валидация - больше, чем 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?Я плохо знаком с языком: (

Ответы [ 2 ]

2 голосов
/ 24 августа 2010

Я думаю, что правильным решением было бы наличие метода валидации для каждого достижения:

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; }
});
1 голос
/ 24 августа 2010

Указатели на функции в Java (и вообще в любом объектно-ориентированном языке) обычно заменяются полиморфными объектами.

По поводу отсутствия жесткого кодирования проверки, я не думаю, что стоит написать механизм правил длячто усилия будут гораздо выше.Что вы можете сделать, так это объединить достижения того же типа, что и объекты одного класса, с полем, имеющим различные значения порогов.

...