Как иметь константы со специфическими связанными методами

Предположим, у вас есть класс для хранения информации об атаках в игре (это не мой случай использования, но практически аналогичный и наиболее понятная аналогия, о которой я мог подумать). Каждая атака имеет имя (String) и силу (int) (вероятно, будут другие поля, но это всего лишь пример). И вы хотите получить доступ к информации о каждом шаге в игре.

Для меня это было бы достаточно просто реализовать с использованием класса Attack, а затем сохранить каждую атаку в качестве завершенных экземпляров Attack в некоторых классах Attacks.

Но предположим, что некоторые движения имеют strength которая меняется при определенных обстоятельствах. Для нетривиального поведения я бы предположил, что для этого может потребоваться определенный метод, который принимает параметры ("обстоятельства", при которых происходит эта вариация) вызывает некоторый дополнительный эффект, например, имеющий более высокую strength при определенных обстоятельствах или исцеление пользователя, или ослабление цели и т.д.

Я ищу решение проблемы необходимости того, что является фактически константами (все атаки строго определены с точки зрения их поведения), но с некоторыми из них "необязательные" методы.

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

Другим возможным решением было бы иметь абстрактный класс Attack, содержащий необходимые поля (name, strength и т.д.), А также набор, указывающий, указывает ли данная атака определенное свойство (все сохраненные различные возможные свойства в enum в абстрактном классе Attack). Каждый шаг затем будет реализован как подкласс Attack с методами, соответствующими каждому свойству, присутствующему в вышеупомянутом множестве. Это решение предлагает большую гибкость, но для каждого отдельного хода потребуются отдельные классы, которые должны собираться как в памяти, так и в памяти (возможно, в виде карты или набора).

Любая оценка этих идей, или новых идей, была бы оценена по достоинству.

1 ответ

Это идеальное использование для перечисления в Java. У вас есть небольшое фиксированное количество типов атак, которые необходимо обрабатывать полиморфно и нуждаются в индивидуальном поведении.

Простой пример:

public enum Attack {
 MELEE(2) {
 @Override
 public int getDamage(int circumstances) {
 // customized behavior
 }
 },
 RANGED(1);

 private final int baseStrength;

 private Attack(int strength) {
 this.baseStrength = strength;
 }

 public int getDamage(int circumstances) {
 // default behavior for all attacks
 }
}

licensed under cc by-sa 3.0 with attribution.