2011-08-02 14 views
3

このタイプのクラス階層をどのように処理するかについて質問がありました。階層はゲームに関連していますが、私はそれがgamdev上でここに行くのに十分一般的だと思います。私はこの種のことが時折起こると思いますので、私は可能な解決策について興味がありますクラス階層を処理する方法

私のゲームで文字を定義するBaseCharacterという基本クラスがあります。それはベースライン文字を持つためにすべての基本的な統計、ステータス効果の保持者、イベントなどが含まれています。私のゲームロジックのほとんどは、BaseCharacterのエンティティで動作し、必要に応じてキャストします。

そこから、ヒューマノイドクラスを継承し、必要な構造とメソッドを追加してキャラクターに装備(武器、防具など)を加え、最後にヒューマノイドの真中にあるPlayableCharacterクラスを持っています。 EXP、設定可能な能力構造など

だから、クラス構造は単純です:

BaseCharacter --->ヒューマノイド---> PlayableCharacter

この構造はIものの、プレイヤー側の文字を定義するための素晴らしい作品構造をもう少し洗練することを決めるかもしれない。私は階層に「敵」クラスを追加できなければなりません。敵の要件を満たすために、敵や戦利品のテーブルなどを倒すためのEXP /ポイントに関連するデータ構造やメソッドを追加する必要があります。

問題はどこにこれらの構造を追加しますか?私は基本的にすべてのキャラクターが敵のエンティティに必要なメソッド/データ構造を持っていると言っているので、それらをBaseCharacterに追加することは悪い考えです。私は次のようになるクラスの別のストリームを開始することを考えました:

BaseCharacter--->Humanoid--->PlayableCharacter 
      \---->Enemy--->EnemyHumanoid 

ここで、敵はBaseCharacterから継承します。 EnemyHumanoidは、BaseCharacter-> Humanoidからの継承と同じメソッド/データ構造のセットを追加します。これは動作しますが、EnemyHumanoidがHumanoidの要件を満たしているにもかかわらず、EnemyHumanoidをHumanoidにキャストすることはできません。これはまた、私はこれらの2つの継承がオブジェクト/メソッドの全く同じセットを追加するので、冗長性を追加します。

はその後EnemyInterfaceと呼ばれる別々のクラスを使用すると考えられており、このような継承階層で終わるには:

BaseCharacter----->Humanoid----->PlayableCharacter 
    |     |     
    V     V     
    Enemy   EnemyHumanoid 

敵とEnemyHumanoidすべてEnemyInterfaceを実装します。しかし、私は今Enemy < - > Enemy Humanoid関係を失う。私はここで複数の魅力を使うべきですか? (Enemy Humamoid inheirt in Enemy and Humanoid?)は、悪い形であると考えられていますか?これを行うより論理的な方法はありますか?ここの例はかなりシンプルですが、私がクラス階層をさらに分割すると、もっと複雑になります。

すべてのヘルプは、あなたが再利用のための継承を使用する代わりに地獄へのパスであるLSP(http://en.wikipedia.org/wiki/Liskov_substitution_principle)、に付着しているようですね

答えて

1

をいただければ幸いです。

私の一般的なアドバイスは、継承をis-a関係にのみ使用することです。つまり、あるタイプを別のタイプに置き換えることができます。私はそれがより簡単であることがわかったので、ほとんどのソリューションでは継承の構成を好みます。

具体的なケースでは、敵とPlayableCharacterが異なると思われる理由は何ですか?あなたがそれにヒューマノイドを渡して、これらのアイテムを別々に計算することができる、クラス階層の外にEXPとルートテーブルを持つことを検討してください。

C++はマルチパラダイム言語です。 OOソリューションに自分自身を限定する必要はありません。

幸運を祈る!

1

この可能性はありますか?

BaseCharacter----->Humanoid----->PlayableCharacter 
        /\     
        / \     
       Enemy  EnemyHumanoid 

敵のヒューマノイドは、ヒューマノイドの一部の機能のみが必要な場合があります。

0

HumanoidインスタンスをBaseCharacterインスタンスに変換する必要があるかどうかを検討する必要があります。実際にはそうではないことがわかります。あなたは実際にすべてのヒューマノイド文字のセットを反復処理する必要がありますか?

そう定義した場合:

Humanoid 

BaseCharacter->PlayableCharacter (contains Humanoid) 
      \---->Enemy---->EnemyHumanoid (contains Humanoid) 

代替インターフェイスとしてヒューマノイド定義することである

[。あなたは敵の抽象具象EnemyNonhumanoidの定義を行うことを検討する必要があります]、およびgetHumanoidを提供( )メソッドを、それぞれの場合にハンドルとして実装しています。

2

この特定の問題を解決するためにクラス階層を再配置するのではなく、コンポーネントベースのアーキテクチャの研究を行うことをお勧めします(StackUnderblowの回答を参照してください)。基本的に、PlayableCharacterをユニークにするものを記述するクラスを持つ代わりに、ある種の基本コンテナにコンポーネント(またはコンポーネントのセット)を移植することになります。

このアプローチははるかに柔軟で、デザインが進化するにつれてリファクタリングが容易になります。たとえば、敵と人間の両方にアクセスできると思われる機能がある場合、基本クラスにシステムフックを追加し、機能を使用できない敵にオーバーヘッドを導入する必要があります。それは単純な問題を説明する言葉がたくさんありますが、あなたのゲームが進化するにつれて何度も問題が繰り返されます。

Here私の提案に基づいて拡張された良いSO議論です。

Bheeshmarが正しいです、あなたは地獄への道にいます!

1

BaseCharacterクラスを複数の側面でサブクラス化しようとしています(誤って「アスペクト」は正しい単語ですが、私はネイティブの英語のスピーカーではありません)、つまり:

  • フォーム - ヒューマノイド/動物/など
  • アライメント - 敵/友達/など

あなたが観察しているように、これは常に、問題につながる:遅かれ早かれ、あなたは、クラスを作成したいと思いますBaseCharacterの複数のサブクラスから継承する必要があります(通常、各aspecから1つtカテゴリ)、例えば。ヒューマノイド+敵。この場合、複数の継承を使用するか(実装上の問題によりC++では推奨されません)、コードを再設計する必要があります。

通常、最善の解決策は、先に特定したアスペクトに従ってオブジェクトを分割することです。例えば。 BaseCharacterオブジェクトの中には、CharacterForm *とCharacterAlignment *の2つのポインタがあります。次に、CharacterForm(HumanoidForm、AnimalFormなど)とCharacterAlignment(EnemyAlignment、FriendAlignmentなど)をサブクラス化できます。)を個別に作成し、必要に応じて組み合わせます。

このアプローチは、Dan Oが提案したように、コンポーネントベースの設計に向けた最初のステップです。 。

あなたは、あなたが敵を必要とするヒューマノイド作成し、動物の後に例えば前回のサブクラス(とは異なる意味でそのベースのサブクラスであるサブクラスを作成する自分自身を見つけるたびに似た何かをする必要があり - >これは、明らかですあなたのBaseCharactersを分類する別の方法)。経験則では、すべてのクラスはという1つの側面に従ってサブクラスのみである必要があります。

0

これはいかがですか?

BaseCharacter

IBehaviour

HumanoidBehaviourインタフェースであるIBehaviour

BaseCharacterの実装はIBehaviour

Enemyが含まれるBaseCharacterを継承しHumanoidBehaviour

0123を含んでいます

PlayableCharacterBaseCharacterを継承し、HumanoidBehaviour

が含まれているので、論理的に、私たちは買ってあげる:Enemyがある-BaseCharacterあり、行動HumanoidBehaviourを。また、素敵な例を持っているfunny book

あり

おそらくStrategy design patternはここ 参考になります

関連する問題