從一個虛構的遊戲引擎API考慮這個例子功能:使用-1 API函數作爲特殊值取數值參數
function Entity.SetHealth(Number health)
做不好有這樣的函數接受
-1
作爲參數,造成,在這種情況下,該實體成爲無敵?我寧願使用兩個額外的功能:
Entity.SetInvincible
和Entity.GetInvincible
?
請注意,這個無敵和健康的例子真的只是由我組成。
從一個虛構的遊戲引擎API考慮這個例子功能:使用-1 API函數作爲特殊值取數值參數
function Entity.SetHealth(Number health)
做不好有這樣的函數接受-1
作爲參數,造成,在這種情況下,該實體成爲無敵?
我寧願使用兩個額外的功能:Entity.SetInvincible
和Entity.GetInvincible
?
請注意,這個無敵和健康的例子真的只是由我組成。
你可以做很多更糟糕的事情,並且我在許多遊戲引擎和UI框架中經常發現許多不同任務的確切方法(例如,在命令中重複運動,設置重複-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 > *
...
Yikes,_Health,_Value,health,value,all all into a big mess。修正了代碼(我希望)。 –