7

種類が異なる有限数のアイテムを考えると、それらをスタックされた列挙型と列挙型コンストラクターで表すのが良いですか、それともサブクラス化するのが良いですか?それとも、より良いアプローチがありますか?

コンテキストを説明するために、私の小さなRPGプログラム(皮肉なことに単純なはずです)では、キャラクターのインベントリにさまざまな種類のアイテムがあります。アイテムは、タイプ、用途、効果によって異なります。

たとえば、インベントリの1つのアイテムは、ユーティリティ属性を調整するグレムリンと呼ばれる呪文の巻物です。別のアイテムは、戦闘で使用され、ダメージを与えるモートと呼ばれる剣である可能性があります。

私のRPGコードでは、在庫アイテムを表す2つの方法を試しました。1つの方法は、サブクラス化(たとえば、InventoryItem-> Spell-> AdjustingAttributes; InventoryItem-> Weapon-> Sword)を行い、必要に応じて各サブクラスをインスタンス化し、GremlinやMortなどの名前を割り当てることでした。

もう1つの方法は、列挙型と列挙型コンストラクターをスタックすることでした。たとえば、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. 

}

これらの2つのアプローチよりも優れたJavaプログラミング手法はありますか?または、これらが唯一の方法である場合、2つのうちどちらが優れていますか?よろしくお願いします。

4

3 に答える 3

8

列挙型は、静的データのみを保持し、論理を最小限に抑える(できればロジックをまったく保持しない)場合に適しています。オブジェクトの動作が種類によって異なる場合は、通常、サブクラスとして実装することをお勧めします。

他の人が述べたように、オブジェクトに属性を追加する可能性が非常に高く、これらの属性はすべての種類に意味があるわけではありません。例えば。色属性は武器には意味がありますが、呪文には意味がありません。その場合、武器と呪文は同じ列挙型にあるべきではありません。

于 2010-04-21T07:33:44.187 に答える
6

アイテムに新しい属性を追加する場合は、サブクラスとして実装する方が簡単な場合があります。このようにして、アイテムのグループが新しい属性を取得すると、それはすべてのサブクラスに伝播されます。

たとえば、すべての種類にWeapon特定の重みが割り当てられている場合は、その属性をそのクラスに追加するだけです。その後、この属性はサブクラスに伝播されます。

本質的により静的であり、したがって直接タイプを割り当てることができる他のものに関しては、列挙型が適しています。私はここで自由に考えているので、それに割り当てられるWeapon可能性があると思います:DamageType

public abstract class Weapon {

public enum DamageType {

 CUT,
 SMASH,
 PIERCE;
}

private DamageType damageType;
于 2010-04-21T07:35:42.473 に答える
6

あなたが説明する文脈では、列挙型定義ではなくクラス階層を使用し、この階層をインターフェースで補足することを検討します。例えば

/**
 * 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 {
}

このアプローチの主な利点は、特定のオブジェクトをさまざまなコンテキストで(InventoryItemsまたはsのリストとしてUsable)処理できることです。私が列挙型から明確に離れるもう1つの理由は、アイテムの動作を定義する可能性が高く(たとえばspell.cast(Person))、これは列挙型IMHOではうまく機能しないためです。

于 2010-04-21T07:44:39.947 に答える