2011-06-22 28 views
1

從一個虛構的遊戲引擎API考慮這個例子功能:使用-1 API函數作爲特殊值取數值參數

function Entity.SetHealth(Number health) 
  • 做不好有這樣的函數接受-1作爲參數,造成,在這種情況下,該實體成爲無敵?

  • 我寧願使用兩個額外的功能:Entity.SetInvincibleEntity.GetInvincible

請注意,這個無敵和健康的例子真的只是由我組成。

回答

1

你可以做很多更糟糕的事情,並且我在許多遊戲引擎和UI框架中經常發現許多不同任務的確切方法(例如,在命令中重複運動,設置重複-1表示「永遠重複」)。如果你把所有的東西都做對了,那麼批評這個設計選擇只是一個挑剔。

這就是說,語義是非直觀的(-1是無敵的?呵呵?),所以最好有額外的功能。

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 > * 
    ... 
+0

Yikes,_Health,_Value,health,value,all all into a big mess。修正了代碼(我希望)。 –