2010-08-24 4 views
1

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

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

Например:

Достижение - 10000 очков!
Типа - точка общей
Значение (Х) - 10000
условие - 1
Validation - больше, чем X

против

Достижения - Ультра-осколочной
Типа - убивает
Value (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? Im новый для языка :(

+0

В java нет указателей на функции. –

+0

@Shengyuan Lu Я думаю, что он/она знает, что в java нет указателей на функции. @FlyingStreudel Мой совет - ждать появления Java 7 Closures. –

ответ

2

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

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 Другой вариант, чтобы предотвратить наследование (и использование композиции) заключается в использовании нечто похожее на 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; } 
}); 
+0

Да, это единственное решение, с которым я мог придумать, но я пытался найти способ, который не требовал абстракции базового класса :(Если все остальное не сработает, я вернусь к этому. * edit * err not abstraction но да .. – FlyingStreudel

+0

@FlyingStreudel: Почему вы пытаетесь избежать этого? –

+0

Делайте это как можно больше для удовольствия, так как я являюсь экстерсисом в технике программирования. Я хочу посмотреть, есть ли способ достичь такой же функциональности, не имея подтипа – FlyingStreudel

1

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

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