世上最糟糕的兩個變數名

aqee發表於2012-08-30

  最近我對Steve McConnell的著作《程式碼大全(Code Complete)(第二版)》做了技術校對,這本書將在六月份出版。 他真是用心良苦,竟然用掉了整整一章的篇幅來討論如何給變數命名。 但有個問題,他只是點到為止,並沒有深入的探討,這個問題就是:有兩個世上最糟糕的變數名稱。 請允許我就此問題發表拙見。

  糟糕的變數名幾乎到處都是。 常見的一種情況是人們喜歡把變數名的到很短、但變數的生存範圍又太大,比如,有人會在整個程式裡使用像 $n 這樣的變數。 有些程式設計師可能會知道,在 TRS-80 BASIC語 言裡, 只是變數名的前兩位字元是有意義的,以至於我們程式設計是必須把一個手抄本的變數名錶格放在鍵盤旁邊參考。

  有些時候你會發現某些人命名變數的簡化策略是把單詞中的母音去掉,用此來替換簡單的擷取的方式,於是本來是 $cust 的變數名變成了 $cstmr。我很懷疑人們能否分清這個變數是代表 customers 呢,還是表示 costumers!

  有時候你會發現有些變數名是故意起的很怪,作者覺得這樣做非常有趣,而不是非常有用。我曾經看到一個迴圈語句裡被命名為 $crap(屎) 的變數。我的一位同事在維護舊程式碼時,把一個函式命名為 THE_LONE_RANGER_RIDES_AGAIN() (“徘徊者”號航天器又能起飛了)。 這類變數名都不是我在這裡要說的糟糕的變數名。

  關於變數命名規範之爭通常會演化為一場關於宗教信仰的戰爭,但是,我確有十足的信心來宣佈這 世上最糟糕的變數名 是:

$data

  當然,它確實表明這是個資料!它表明變數裡能放什麼東西!它表明變數裡什麼都能放!就像是你收拾打包你的物品,把它們移到一個新房子裡,你在包箱外 面寫著,用很粗的黑字寫著:“東西”。

  即使這個變數是個函式指標,它裡面的資料也是告訴程式何處去執行這個函式。 即使這個變數是 undef 或 NULL, 包含這種值的變數本身就具有特殊意義。

  變數名應該表明變數裡裝載了什麼資料。 問問自己“是什麼資料”,這是優化你的變數命名最簡單的方法。我曾經看到有人用 $data 表示從資料表裡讀取的一條記錄。寫法就像這樣:

    $data = read_record();
    print "ID = ", $data["CUSTOMER_ID"];

  問問自己”是什麼資料“將會立即給你一個好的命名思路。 命名成 $record 就好多了。 $customer_record 那就更好了。

  我開篇就說過有兩個最糟糕的變數名,我相信沒有人會反對我提出這 世上第二糟糕的變數名 是:

$data2

  非常普遍,當任何一個變數依賴於序列號來區別跟它相似的資料時,你需要立即重新考慮這個變數命名。 常常你會看到像這樣的程式碼:

    $total = $price * $qty;
    $total2 = $total - $discount;
    $total2 += $total * $taxrate;
    $total3 = $purchase_order_value + $available_credit;
    if ( $total2 < $total3 ) {
        print "You can't afford this order.";
    }

  讓我們用考古學的方式挖掘這段程式碼。 首先,這段程式碼只是指明瞭訂單的總額, $total。如果沒有其它的,這個 $total 定義的無可挑剔。 可不幸的是,有人在此之後加了一段程式碼,用來處理折扣和稅率,偷懶的將它們存到 $total2裡。 最後,有人又加了一段,用來檢查使用者支付的總值,並把變數命名為 $total3。

  這段程式碼裡最關鍵的能反映問題的一句是:

    if ( $total2 < $total3 )

  如果你不回頭看看這兩個total都是存的什麼,你不可能知道這句是在計算什麼。

  如果你正在面臨著要給某變數命名成 $total2 的問題, 請先把已有的變數名變的更有意義。 花上幾分鐘的時間,給這些變數合適的名稱。這個層面上的程式碼反省是你能做到的最簡單的,成本最低的,形式最安全的反省, 特別是當這個變數在一個封閉的子程式裡時,更需要這樣。

  讓我們對上面這段糟糕的程式碼做一個簡單的查詢替換過程:

    $order_total = $price * $qty;
    $payable_total = $order_total - $discount;
    $payable_total += $payable_total * $taxrate;
    $available_funds = $purchase_order_value + $availble_credit;
    if ( $payable_total < $available_funds ) {
        print "You can't afford this order.";
    }

  變化的只有變數名,這樣一來這段程式碼就很容易理解了。 現在所有的 _total 變數都不存在歧義了。 而且,你會發現: if 比較語句寫顛倒了。 有效的命名讓這種錯誤極易發現。

  這種以數字結尾的變數並不是都不好,有個例外。如果這個實體本身就是以數字結尾的,變數也應該留下這個數字。對於跨省的國道的變數命 名就應該像 $route31。如果你把它改成 $route_thirty_one 那就有點傻了。
最後,記著這些命名習慣對於定義程式變數和定義檔名同樣適用。 我通常也不願意花太多的時間去考慮檔案的命名,當然這是另外一個話題了。

  還有什麼其他的讓你抓狂的命名現象?

英文原文:the_worlds_two_worst_variable

相關文章