9

私はWeb開発者(趣味としてのゲーム開発者)であり、次のパラダイムを何度か使用しているのを見てきました。(サーバーアーキテクチャの開発とビデオゲームの開発作業の両方で。)それは本当に醜いようですが、回避策はわかりません。最近気付いたので、ゲーム開発で例を挙げましょう。これは私が取り組んできたRPGです。戦闘が開始されるたびに、CombatEngineは戦闘員の2つのパーティを作成します。すべての戦闘員は、特定の戦闘員に関連付けられた人工知能オブジェクトを設定します。このオブジェクトは、明示的なコマンドを受け取らないプレーヤーの動きを指示する役割を果たします。

public class Combatant {

    ArtificialIntelligence ai = null;

    public Combatant()
    {
        // Set other fields here.

        this.ai = new ArtificialIntelligence(this);
    }

}

私が気に入らない点は次のとおりです。内部フィールド(ArtificialIntelligence)は、適切なアクションを指示するためにいくつかの戦闘員フィールドを必要とするため、建設中に戦闘員を受け入れます。したがって、便宜上、ArtificialIntelligenceオブジェクトへの引数として渡された戦闘員への参照を保持しますが、そのオブジェクトにはaiオブジェクト自体への参照が含まれています。これはこの奇妙な再帰を作成しますが、それを回避する方法がわかりません。AIオブジェクトには、戦闘員に固有のフィールドが大量に必要なため、オブジェクト全体を渡しましたが、オブジェクトに、上にある戦闘員に含まれるaiフィールドへの参照が含まれる方法が好きではありません。上にあるaiクラスに含まれるフィールド。これは悪い習慣ですか、それとも単に考えすぎですか?

4

2 に答える 2

9

ここには「設計」の問題はありませんが(これは渡す参照にすぎません)、重要な考慮事項の1つは、他のクラスに渡す前にすべてのフィールドを初期化する必要があることです。そうしないと、他のクラスが一貫性のない状態でthisアクセスできるようになります。これは、コンストラクターから「エスケープ」するthisことと呼ばれることもあります。this

これをしないでください...

public class BadCombatant {

    ArtificialIntelligence ai = null;
    String someField;

    public BadCombatant() {
        this.ai = new ArtificialIntelligence(this);
        // Don't do this - ArtificialIntelligence constructor saw someField as null
        someField = "something"; 
    }
于 2012-09-19T03:18:15.187 に答える
5

私は間違いなく循環依存を避けます。救助には単一責任の原則があります。ArtificialIntelligenceを戦闘員に動作させることで、戦闘員の人工知能を参照する必要をなくすことができます。代わりに、ArtificialIntelligenceに依存するすべてのコードをCombatantからArtificialIntelligenceに移動します。CombatEngineは次のことを行います。

  1. Artificialntelligenceとは関係のないIndependentCombatantインスタンスを作成します。

  2. Artificalintelligenceの適切なインスタンスを作成し、以前に作成した戦闘員に渡します。

または、CombatantとArtificialIntelligenceが渡されるCombatControllerという新しいクラスを作成することもできます。CombatEngineは次のことを行います。

  1. 他のクラスに依存しない戦闘員を作成する

  2. 他のクラスに依存せずに人工知能を作成する

  3. CombatControllerを作成し、使用するCombatantオブジェクトとArtificialIntelligenceオブジェクトを渡します。CombatControllerは、戦闘員を制御するためのメソッドを公開し、AIの動作を処理する必要があります。

上記のアプローチのどちらを使用するかに関係なく、煩わしい循環依存関係を排除します。

携帯電話からこの回答を入力していて、フォーマットが面倒なので、コード例を提供できず申し訳ありません。

于 2012-09-19T07:31:20.300 に答える