Каковы некоторые методы динамической проверки для универсального класса?

1

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

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

Например:

Достижение - 10 000 очков!
Тип - итоговая сумма
Значение (X) - 10 000
Условия - 1
Валидация - больше X

против.

Достижение - Ультра-фрагмент
Тип - убивает
Значение (X) - 10
Тип - время
Значение (Y) - 10 секунд
Условия - 2
Валидация - по крайней мере X меньше Y

Я пытаюсь избежать hardcoding функции проверки для каждого достижения, поскольку они в основном являются обобщенными, и единственная разница заключается в том, как они проверяются.

Как класс достижений выглядит примерно так:

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

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

Я пытаюсь придумать способ сделать это без указателей функций, и я терплю неудачу. Кроме того, можете ли вы использовать указатели на функции в java? Im новое для языка: (

  • 0
    Там нет указателей на функции в Java.
  • 0
    @Shengyuan Lu Я думаю, он / она знает, что в Java нет указателей на функции. @FlyingStreudel Мой совет - дождаться закрытия Java 7.
Теги:
algorithm
achievements

2 ответа

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

EDIT Другим вариантом предотвращения наследования (и использования композиции) является использование чего-то похожего на шаблон стратегии .

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; }
});
  • 0
    Да, это единственное решение, которое я мог придумать, но я пытался найти способ, который не требовал абстракции базового класса :( если все остальное терпит неудачу, я вернусь к этому. Edit err не abstraction, а yea ..
  • 0
    @FlyingStreudel: Почему вы пытаетесь избежать этого?
Показать ещё 10 комментариев
1

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

О том, что я не жестко кодировал валидацию, я не думаю, что стоит написать для этого механизм правил, усилия будут намного выше. То, что вы можете сделать, - унифицировать достижения того же типа, что и объекты того же класса, с полем, имеющим разные значения пороговых значений.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню