У меня есть вопросы о паре техник, которые я использую при разработке класса.Я объявил некоторые из его членов как public final вместо private, и конструктор вызывает переопределенные методы.Я знаю, что это обычно считается плохой практикой, но я думаю, что они могут быть оправданы в моей ситуации, и я хочу знать, что думают другие.
Это мой класс:
/** A monster that fights other monsters in my program */
public abstract class Creature
{
/**
* Keeps track of the different values determining how powerful a Creature
* is.
*/
public static class Stats
{
//subclass definition here.
//This subclass contains a lot of public static members like this:
public final CurMax health;
}
public final static Random RANDOM = new Random();
//These are the public final members that I'm wondering about.
public final Stats stats;
public final Attack[] attacks;
public final Stopwatch turnStopwatch;
private String name;
//This is the constructor I'm wondering about.
public Creature()
{
initMembers();
stats = generateStats();
name = RandomValues.NAMES[RANDOM.nextInt(RandomValues.NAMES.length)];
attacks = generateAttacks();
turnStopwatch = new Stopwatch(false);
}
/**
* Define any member variables for subclasses in Creature in this method,
* not in the subclasses' constructors.
*
* Using the Creature class requires the Constructor to call overridable
* methods. This is deliberate because the constructor assigns values to
* final member variables, but I want the values of these variables to be
* determined by subclasses. This method allows subclasses to assign values
* to their own member variables while still controlling the values of the
* final variables in the Creature class.
*
* @see #generateAttacks()
* @see #generateStats()
*/
protected abstract void initMembers();
protected abstract Stats generateStats();
protected abstract Attack[] generateAttacks();
public boolean isDead()
{
return stats.health.getCurrent() <= 0;
}
public String getName()
{
return name;
}
}
Я объявил переменные-члены как public final, потому что я планирую использовать их часто, и создание методов для контроля доступа к ним было бы утомительно.Например, я планирую писать такие строки во всей программе:
creature.stats.health.getCurrent();
creature.stats.health.resetMax();
Чтобы не предоставлять публичный доступ к статистике и работоспособности, потребовались бы такие методы написания, как getCurrentHealth()
и resetMaxHealth()
Класс Существо.В классе CurMax помимо конструкторов имеется 10 методов, а в классе stats есть 12 членов типов, похожих на CurMax, так что для этого потребуется написать более 100 дополнительных функций в классе Creature.В свете этого, уместно ли то, как я использовал публичные финальные члены?Если это не так, каков будет другой метод, который был бы более удовлетворительным?
Если использование открытых финальных элементов в порядке, как насчет использования переопределенных методов в конструкторе?Я хочу позволить каждому подклассу Существа определять свой собственный алгоритм для создания статистики и массива атак.Например, одно существо может выбрать несколько случайных атак из списка, в то время как другое выбирает атаки, которые эффективны против другого конкретного существа.Поскольку stats
и attacks
являются конечными переменными, они должны быть определены в конструкторе Существа.Мой обходной путь заключается в том, чтобы конструктор вызывал переопределенные методы, чтобы подклассы могли определять значения stats
и attacks
, оставляя фактическое назначение в конструкторе.
Я понимаю, что основной риск связан с использованием переопределенныхМетоды в конструкторах состоят в том, что переопределенные методы будут вызываться до того, как подкласс получит возможность определять свои собственные члены данных.Я думаю, что этого избежать в моей ситуации, потому что методы generateStats () и generateAttacks () существуют только для использования в конструкторе.Кроме того, я добавил еще один абстрактный метод, initMembers, который вызывается в конструкторе Creature раньше всего.Подклассы могут определять любые переменные-члены в этой функции перед вызовом generateStats () и generateAttacks ().
Конструкторы для Stats и Attack являются большими, поэтому я не могу просто передать объект Stats и массив Attacksконструктору.Вызов super () в конструкторах подклассов будет недопустимо длинным.
Оправдан ли способ использования переопределяемых методов в конструкторе Creature?Если это не так, что еще мне делать?