[獨自murmur]避免"魔術數字"(magic numbers)

  • 5816
  • 0

[獨自murmur]避免"魔術數字"(magic numbers)

參考來源:Avoid "magic numbers" from Code Complete2, Ch12.1. Numbers in General

內容摘要:

 

Avoid "magic numbers" Magic numbers are literal numbers, such as 100 or 47524, that appear in the middle of a program without explanation. If you program in a language that supports named constants, use them instead. If you can't use named constants, use global variables when it's feasible to do so.

Avoiding magic numbers yields three advantages:

  • Changes can be made more reliably. If you use named constants, you won't over-look one of the 100s or change a 100 that refers to something else.
  • Changes can be made more easily. When the maximum number of entries changes from 100 to 200, if you're using magic numbers you have to find all the 100s and change them to 200s. If you use 100+1 or 100-1, you'll also have to find all the 101s and 99s and change them to 201s and 199s. If you're using a named constant, you simply change the definition of the constant from 100 to 200 in one place.
  • Your code is more readable. Sure, in the expression
for i = 0 to 99 do ...

you can guess that 99 refers to the maximum number of entries. But the expression

for i = 0 to MAX_ENTRIES-1 do ...

leaves no doubt. Even if you're certain that a number will never change, you get a readability benefit if you use a named constant.

Use hard-coded 0s and 1s if you need to The values 0 and 1 are used to increment, decrement, and start loops at the first element of an array. The 0 in

for i = 0 to CONSTANT do ..

is OK, and the 1 in

total = total + 1

is OK. A good rule of thumb is that the only literals that should occur in the body of a program are 0 and 1. Any other literals should be replaced with something more descriptive.

 

簡單的說,
當code裡面出現非0與1的數字時,
如果沒有明確的解釋(例如註解)或永恆不變的事實時,
即代表這code有改善的空間。

 

用比較誇張的例子來說的話,就是一年365天,但是四年一次閏年會是366天,
如果code裡面直接用365或366可能都比較不妥當。
再假設這段CODE去火星上,可能就不能用了,因為火星的一年並非365天或366天。

 

另一個誇張的例子,以現在的世界來說一分鐘就是60秒,
所以程式裡面算時間總量,一分鐘用60秒計算是相當合乎常理的,
但假設未來發現原來一分鐘是60.125秒,倘若要修改程式,就要把所有使用到一分鐘60秒的code都改成60.125秒。
可以想像這樣要改多少CODE。(全文replace是挖東牆補西牆的作法)

 

magic numbers,不論在程式的可讀性與未來的維護,都會造成相當大的風險跟困擾。
而這也是常在code review的時候,看到的小問題。

 

for loop 上的數字,應該只會有0跟1,其他的數字,應使用Constant來定義該數字的實際意義為何。
這種例子,有點類似「錯誤訊息」不應該hard-coded寫死,而用一個訊息id來代替,該id value與text的對應是可供調整的。


blog 與課程更新內容,請前往新站位置:http://tdd.best/