史上最糟糕的两个变量名

fmms 12年前
   <p>        作为一个程序员,“起名字”是他们工作中非常重要的一部分。Phil Karlton 就说过:“在计算机科学领域,有两大难题,如何验证缓存和如何给各种东西命名。”虽然很难,但是每次在写代码的时候,给事物起名字又是不可回避的工作。无 论是程序变量名还是数据库表名或者是表里的列名,甚至是文件系统中的文件名,以及你的项目名称、产品名称,给这些东西起名字可不是个轻松活儿。</p>    <p>        糟糕的命名方式随处可见。你会发现,有的变量名字起得太短,根本没法提供足够的描述信息。或许有这个问题的人都做过 TRS-80 BASIC 程序员,在这种 BASIC 语言里,无论你起多长的变量名,只有名字的头两个字母有效,所以那个时候的程序员不得不在键盘边儿上放个笔记本,以便将很短的变量名称和他们的对应含义记 录下来,这样才能不搞混淆。</p>    <p>        有的时候,你会发现这样的命名方法:直接将变量名称中的原音字母省略,以此来缩短变量的长度。这种方法被用来替代常用的“截断法”,也就是简单 地把字母截断来缩短长度。比如你可以用$cstmr (原音省略)来代替$cust (直接截断). 但是,对于 customers(顾客)和 costumers(服装提供商)这两个单词来说,原音省略法就会造成混淆(customers 和 costumers 采用原音省略法,其结果都是 cstmr)。更糟糕的是,$cstmr 缺乏原音字母,打字的时候会更加别扭,而且从读音的角度来说,也很难对其进行发音。</p>    <dl>     <dt>     <a title="tsr80" rel="lightbox[18304]"><img title="tsr80" alt="史上最糟糕的两个变量名" src="https://simg.open-open.com/show/e5b5e3a2c9d3b1412822cfc4e78c05b1.jpg" width="300" height="300" /></a>     </dt>   </dl>    <dl>     <dt>     <br />     </dt>     <dd>     TSR80计算机,只支持 4 位的变量名     </dd>   </dl>    <p>        还有一种人为的特殊命名方式,有的时候程序的作者只是为了小幽一默,所以起了些有趣的名字。我就曾经见到过有人把循环变量命名为$crap (crap 在英语里是轻微的咒骂,跟 damm,shit 这种词语差不多——译者注),我的一个同事告诉我,他在给一段代码做整理的时候,看到过有个函数被命名 为:THE_LONE_RANGER_RIDES_AGAIN ()。虽然这样的命名方式非常特殊,但是他们并不属于我说的“糟糕”的命名的范畴。</p>    <p>        虽然我很清楚,对于命名规范这种事情,大家是公说公有理,婆说婆有理,但是,我还是非常自信地宣布,我认为,史上最糟糕的命名是:<strong>$data!</strong></p>    <p>        是的!必须是$data! 这个命名完全是循环定义,实际上就是一句废话。就仿佛你把你们家所有的东西都扔到一个行李箱里,然后在行李箱上面贴个条,赫然写着:“东西”</p>    <p>        正确变量命名应该写清楚变量的数据类型。因此在命名是考虑数据类型是一个很好的提升命名质量的办法。我有一次在看一段读数据库表记录的代码时,看到了$data 这个名字,大概像下面这样:</p>    <div class="cnblogs_code">    <pre>$data = read_record ();     print <span style="color:#800000;">"</span><span style="color:#800000;">ID = </span><span style="color:#800000;">"</span>, $data[<span style="color:#800000;">"</span><span style="color:#800000;">CUSTOMER_ID</span><span style="color:#800000;">"</span>];</pre>   </div>    <p>        如果这时候问问:“$data 是什么数据类型呢?”,然后你就很想给它换个名字了。把名字改成$record 是一个好的开始。进一步改成$custormer_record,就更好一些了。</p>    <p>        模糊的命名相当糟糕,糟糕程度紧随其后的就是,长得几乎一样,无法分辨的变量名。因此,有史以来第二糟糕的变量名就是:<strong>$data2</strong>.</p>    <p>        总的来说,任何仅仅依靠数字编号来区分的变量名都应该被<a title="重构" href="http://www.amazon.cn/gp/product/B003BY6PLK/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=vastwork-23&linkCode=as2&camp=536&creative=3200&creativeASIN=B003BY6PLK" rel="nofollow" target="_blank">重构</a>。马上举个例子给你看,你就明白了:</p>    <div class="cnblogs_code">    <pre>$total = $price * $qty;     $total2 = $total - $discount;     $total2 += $total2 * $taxrate;     $total3 = $purchase_order_value + $available_credit;   <span style="color:#0000ff;">if</span> ( $total2 < $total3 ) {         print <span style="color:#800000;">"</span><span style="color:#800000;">You can't afford this order.</span><span style="color:#800000;">"</span>;     }</pre>   </div>    <p>        你可以发现,要读懂这个代码就跟读甲骨文一样痛苦。很明显,这个程序的目的就是要计算订单的总花费,$total. 如果程序的逻辑没有问题,那么$total 这个变量名也算是恰如其分。但是,偏偏有人修改了这个程序,给添加了计算折扣和税率的功能,然后他还在变量命名上偷懒,直接起了个$total2, 更可恨的是,还有其他人在这个程序里计算了用户的可用账户金额,然后直接起名叫$total3!</p>    <p>        真正倒霉催的是下面这行代码:</p>    <div class="cnblogs_code">    <pre><span style="color:#0000ff;">if</span> ( $total2 < $total3 )</pre>   </div>    <p>        如果你不回头看之前的代码,要想知道这句代码的意义是完全不可能的。所以你必须往回阅读,看看哪个变量究竟是什么意思。</p>    <p>        如果你看到了类似像$total2这样的变量,那就应该把这个名字改得更加具体一些。花 5 分钟的时间让这些变量名称变得更加合理。这个层面上的软件重构是最简单,代价最小,也是最安全的,尤其是在你要修改的变量是个局部变量的时候。</p>    <p>        让我们用最简单的“搜索-替换”功能来解决我们之前发现的问题</p>    <div class="cnblogs_code">    <pre>$order_total = $price * $qty;     $payable_total = $order_total - $discount;     $payable_total += $payable_total * $taxrate;     $available_funds = $purchase_order_value + $available_credit;   <span style="color:#0000ff;">if</span> ( $payable_total < $available_funds ) {         print <span style="color:#800000;">"</span><span style="color:#800000;">You can't afford this order.</span><span style="color:#800000;">"</span>;     }</pre>   </div>    <p>        经过修改后,唯一变化的就是变量名,而且代码变得简单易懂了。现在对于每个_total,就不存在二义性的问题了。看看我们发现了什么:原先 if 语句中的两个比较变量的位置写反了。有效的命名方法让我们能够更快地发现错误。</p>    <p>        通常,我们都认为用数字作为变量的结尾是不好的命名方法,但是有一个例外。如果变量描述的实体本身就是以数字结尾的,那变量名最好也是以数字结 尾。比如,如果我们要定义一个 SHA-1哈希实体,那干脆就把它命名为$sha1,这样就很好,你完全没有必要把它搞成$sha_one,然后来避免在变量名中使用数字。</p>    <p>        在我完成了对本文的第一版后,我创立了自己的命名规则,并使用 Perl::Critic 包来检测上述提到的两种命名问题。我制作的插件 Perl::Critic::Bangs 可以检测出这两种问 题:ProhibitVagueNames 和 ProhibitNumberNames.</p>    <p>        还有哪些其他的糟糕的命名方法逼得你发疯?你自己有去做些什么纠正这些错误么?</p>    <p>        英文原文:<a title="the-worlds-two-worst-variable-names" href="/misc/goto?guid=4958339998435694529" rel="nofollow" target="_blank">The world’s two worst variable names</a>  编译:<a href="/misc/goto?guid=4958338613453938753" target="_blank">伯乐</a>在线 – <a title="史上最糟糕的两个变量名" href="/misc/goto?guid=4958339999965320806" target="_blank">黄小非</a></p>