1

架空のゲーム エンジン API の関数の例を考えてみましょう。

function Entity.SetHealth( Number health )
  • -1このような関数がパラメーターとして受け入れられ、この場合、エンティティが無敵になる原因となるのは悪いことですか?

  • 2 つの追加関数を使用する必要があります:Entity.SetInvincibleEntity.GetInvincible?

無敵と健康に関するこの例は、実際には私が作成したものであることに注意してください。

4

2 に答える 2

1

あなたができるもっと悪いことはたくさんあります、そして私はさまざまなタスクのための多くのゲームエンジンとUIフレームワークで非常に頻繁にその正確なアプローチを見ます(例えば、動きを繰り返すコマンドで、繰り返しを-1に設定することは意味します「永遠に繰り返す」)。他のすべてがほぼ正しい場合、このデザインの選択を批判するのはつまらないことです。

とは言っても、セマンティクスは非直感的 (-1 は無敵ですか?) なので、余分な関数を用意した方がよいでしょう。

于 2011-06-22T16:21:56.637 に答える
1

通常、マジック ナンバーは悪い兆候ですが、禁止すべきだとまでは言いません。言い換えれば、-1それ以外の場合は不正な値である場合、それを使用できますが、少なくとも定数を作成して、そのメソッドの呼び出しが次のようになるようにします。

someEntity.SetHealth(Health.Infinite)

または同様に、定数の命名はあなた次第です。

ただし、(私の意見では) より良い方法は、値をカプセル化して追加のデータを与えることです。たとえば、C# で次のような型を作成できます。

public struct Health
{
    private readonly int _Value;
    public int Value { get { return _Value; } }

    public Health(int value)
    {
        if (value < 0 || value > SOME_ARBITRARY_MAX_NUMBER)
            throw new ArgumentOutOfRangeException("value");
        _Value = value;
    }

    public static Health Infinite
    {
        get
        {
            Health result = new Health(0);
            result._Value = -1;
            return result;
        }
    }

    public bool IsInfinite
    {
        get
        {
            return _Value == -1;
        }
    }
}

次に、必要な比較メソッド、演算子なども追加して、たとえば次のことができるようにします。

Health a = Health.Infinite;
Health b = 100;               // automatic type coercion
if (b < a)                    // custom operator, knows that Infinite > *
    ...
于 2011-06-22T16:24:35.370 に答える