1

私がスポーツゲームを作成しているとしましょう。このゲームには、プレーヤーがプレイ、攻撃、防御などできるさまざまな位置があります。そこで、基本クラスを作成することから始めます。

public abstract class Position
{
 public abstract string Name
 {
  get;
 }
}

とサブクラス...

public class Defender : Position
{
 public override string Name
 {
  get { return "Defender"; }
 }
}

等々。これはすべて問題ありません。

しかし今、私はこれらのオブジェクトを作成するための関数が必要です。位置による作成機能が必要です。したがって、考えられる解決策の1つは、すべての位置の列挙型を作成し、この値を、列挙型をオンにして適切なオブジェクトを返す関数に渡すことです。しかし、これは私のコードの臭いアラームをトリガーします。この魂は、関数内のクラス、列挙型、およびスイッチを結び付けます。

public static Position GetByType(Types position)
{
 switch(position)
 {
  case Types.Defender:
   return new Defender();
... and further terrible code

どのような解決策を見るべきですか?これはどのデザインパターンですか?

4

4 に答える 4

5

これを小規模で行う必要がある場合、特に1つの場所にある場合は、スイッチはそれほど悪くはありません。

これを中規模で行う必要がある場合は、内部を少し改善することを検討することをお勧めします。SteveEllingerの提案は妥当なものです。個人的にIDictionary<MyEnum, Action<T>>は、アクションが問題のクラスの新しいインスタンスを返す場所を使用することを好みます。

これを大規模または構成可能な規模で行う必要がある場合は、構造マップやninjectなどのIoCコントローラー、または最近クールな子供たちが遊んでいるものをチェックする必要があります。

于 2010-10-10T01:52:12.993 に答える
3

ファクトリパターンのように聞こえます。

ただし、列挙型/文字列をオンにして適切なタイプのオブジェクトを返すスイッチケースがあることは悪いことではないかもしれません....それが1つの場所に分離されている限り。

于 2010-10-09T18:04:34.200 に答える
2

確かに、必要なのは抽象ファクトリです。ファクトリの実装のしやすさは、使用している言語によって異なります。たとえば、phpでは可変クラス名を使用できるため、クラス名を送信して新しい$classnameを取り戻すことができます。ただし、他の言語ではこれは許可されていません。実際、あなたの言語がこれを行わない場合、あなたはすでにファクトリクラスを作成しています!

リフレクションを使用してphpの機能をシミュレートする場合を除いて、これほどエレガントな方法はありません。

于 2010-10-09T18:21:46.620 に答える
1

スイッチを処理する1つの方法は、ファクトリに型の配列を宣言させてから、次のように配列へのインデックスとして列挙型を使用することです。

public abstract class Position {
    public abstract string Name {
        get;
    }
}
public class Defender : Position {
    public override string Name {
        get { return "Defender"; }
    }
}
public class Attacker : Position {
    public override string Name {
        get { return "Attacker"; }
    }
}
public static class PositionFactory {
    public enum Types {
        Defender, Attacker
    }
    private static Type[] sTypes = new Type[] { typeof(Defender), typeof(Attacker)};
    public static Position GetByType(Types positionType) {
        return Activator.CreateInstance(sTypes[(Int32)positionType]) as Position;
    }
}
于 2010-10-10T01:31:02.853 に答える