Который является лучшей практикой программирования Java: укладка перечислений и перечислимых конструкторов или разделения на подклассы?

Учитывая конечное число объектов, которые отличаются натуральные, лучше представить их со сложенными перечислениями и перечислимыми конструкторами, или разделить их на подклассы? Или есть ли в целом лучший подход?

Чтобы дать Вам некоторый контекст, в моей маленькой программе RPG (который иронически, как предполагается, прост), символ имеет различные виды объектов в его материально-технических ресурсах. Объекты отличаются на основе своего типа и использования и эффекта.

Например, один объект материально-технических ресурсов является прокруткой написания под названием Гремлин, который корректирует Служебный атрибут. Другой объект мог бы быть мечом по имени Mort, который используется в бою и причиняет ущерб.

В моем коде RPG я теперь попробовал два способа представить предметы хранения. Один путь разделял на подклассы (например, InventoryItem-> Написание-> AdjustingAttributes; InventoryItem-> Оружие-> Меч) и инстанцирующий каждого подкласса при необходимости и присваивающий значения, такие как имена как Гремлин и Mort.

Другой путь был путем укладки перечислений и перечислимых конструкторов. Например, я создал перечисления для itemCategory и itemSpellTypes и itemWeaponTypes, и перечисление InventoryItem было похоже на это:

public enum InventoryItem {
   GREMLIN(itemType.SPELL, itemSpellTypes.ATTRIBUTE, Attribute.UTILITY),
   MORT(itemType.WEAPON, itemWeaponTypes.SWORD, 30);

   InventoryItem(itemType typeOfItem, itemSpellTypes spellType, Attribute attAdjusted) {
   // snip, enum logic here
   }
   InventoryItem(itemType typeOfItem, itemWeaponTypes weaponType, int dmg) {
   // snip, enum logic here 
   }
   // and so on, for all the permutations of items. 

}

Существует ли лучшая практика программирования Java, чем эти два подхода? Или если это единственные пути, какой из этих двух лучше? Заранее спасибо за Ваши предложения.

7
задан Arvanem 21 April 2010 в 07:28
поделиться

3 ответа

В контексте, который вы описываете, я бы рассмотрел возможность использования иерархии классов вместо определений перечислений и дополнения этой иерархии интерфейсами; например

/**
 * Root of class hierarchy.
 */
public interface InventoryItem {
}

/**
 * Additional "parallel" interface implemented by some (but not all)
 * InventoryItems and other non-inventory items.
 */
public interface Usable {
  void use();
}

/**
 * A Spell is in InventoryItem and is also Usable.
 */
public abstract class Spell implements InventoryItem, Usable {
}

public class Gremlin extends Spell {
}

/**
 * A Door is *not* an InventoryItem but can be used.
 */
public class Door implements Usable {
}

Основным преимуществом этого подхода является то, что он позволяет обрабатывать данный объект в различных контекстах (как InventoryItem s или как список Usable ) с). Другая причина, по которой я бы держался подальше от перечислений, заключается в том, что вы, вероятно, определяете поведение своих элементов (например, spell.cast (Person) ), и это не подходит для перечислений IMHO.

6
ответ дан 6 December 2019 в 09:18
поделиться

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

Как уже упоминалось, вы, скорее всего, добавите атрибуты к своим объектам, и эти атрибуты не будут иметь смысла для всех типов. Например. атрибут цвета имеет смысл для оружия, но не для заклинания. В этом случае оружие и заклинание не должны быть в одном и том же перечислении.

8
ответ дан 6 December 2019 в 09:18
поделиться

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

Например, если всем видам оружия назначается определенный вес, вы просто добавляете этот атрибут к этому классу. Затем этот атрибут будет распространяться на подклассы.

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

public abstract class Weapon {

public enum DamageType {

 CUT,
 SMASH,
 PIERCE;
}

private DamageType damageType;
6
ответ дан 6 December 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: