qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請訪問 http://qaseven.github.io/

          程序員如何讓你的變量名更加精確

          程序員如何讓你的變量名更加精確

           

          字體:        | 上一篇 下一篇 | 打印  | 我要投稿  | 推薦標簽: 軟件開發(fā) java

          關(guān)鍵點

            “別人還能把這個名字理解成什么意思?”通過不斷的問自己這個問題來積極檢查每一個命名。

            事實上,這種富有創(chuàng)造性的、不斷嘗試“錯誤理解”的方法,能夠有效的發(fā)現(xiàn)歧義的命名,并修正它們。正如本文中的示例,我們將隨時通過“騎驢看唱本 ——邊走邊瞧”的方式來 探討所見到名字的誤解之處,然后選取一個更好的名字。

            示例:Filter()

            假設(shè)寫了一段代碼來操作數(shù)據(jù)庫結(jié)果的集合:

            results= Database.all_objects.filter("year <= 2011")

            那么,results包含什么數(shù)據(jù)呢?

            所有滿足year<=2011的對象

            所有不滿足year<=2011的對象

            問題的由來是從filter這個有歧義的詞開始的,它沒有清楚表達它的意思是“選取”還是“剔除”。因此,應(yīng)該避免使用filter,它太容易造 成誤解!

            如果這里想要的效果是“選取”,一個更好的名字是select;如果想要的是“剔除”,更好的名字則是exclude。

            為布爾值取名

            當為布爾值變量命名或者函數(shù)返回布爾值的時候,要特別注意真和假所表達出來的真實意思,這里就有一個很危險的例子:

            bool read_password= true;

            這句代碼意思取決于當時怎么閱讀的(沒有其他的意思了),顯然這里有兩種截然不同的理解:

            需要讀密碼

            密碼已經(jīng)被讀過了

            在這個用例下,做好避免用單詞read,可以考慮使用need_password或者user_is_authenticated來代替。

            通常情況下,添加單詞is、has、can或者should可以讓布爾值的意思更加清晰易懂。

            比如說有個函數(shù)叫SpaceLeft(),乍一看,就會想到這個函數(shù)返回的值是數(shù)字。如果需要明確返回值是布爾值,一個更好的名字是 HasSpaceLeft()。

            還有,盡量避免使用反義短句來命名。例如:

          bool disable_ssl= false;

           

            改成如下代碼則更容易理解,同時更契合原意:

          bool use_ssl= true;

            符合用戶期望

            很多名字是帶有誤導(dǎo)性的,因為對于某個名字,用戶自已有一個預(yù)想的定義,但是代碼的意思可能恰恰不是這個意思。如此情況下,最好作出“讓步”并改 變名字,消除 誤導(dǎo)性。

            示例:get*()

            許多程序員都在使用這樣的編碼規(guī)范:某個方法以get開頭來表達一個“輕量級的訪問器”以返回內(nèi)部成員。違反這個規(guī)范將很容易誤導(dǎo)用戶。 避免下面的例子中java代碼段的做法:

          public class StatisticsCollector { public void addSample(double x) { ... } public double getMean() { // Iterate through all samples and return total / num_samples } ...}

            這里,getMean的實現(xiàn)是枚舉過去所有的數(shù)據(jù),并計算其平均值。如果數(shù)據(jù)量很大的時候,這一步的開銷將會是非常大的。但是,一個不了解情況的 程 序員則會很粗心的調(diào)用它并且假設(shè)這是一個很廉價的調(diào)用。

            因此,這個方法應(yīng)該改名成類似computeMean()這樣的,看起來這樣就是一個代價高昂的操作了(或者,另一個選擇就是改寫其實現(xiàn),變成一 個名副其實的輕量級操作)。

            示例:list::size()

            這里講一個C++標準庫里的命名問題。這段代碼導(dǎo)致的結(jié)果是,很難定位和修復(fù)類似導(dǎo)致服務(wù)器龜速運行之類的問題:

          void ShrinkList(list<Node>& list, int max_size) { while (list.size()>max_size) { FreeNode(list.back()); list.pop_back(); }}

            這樣的bug的導(dǎo)致是作者沒有意識到list.size()是一個O(n)復(fù)雜度的操作——它挨個計數(shù)鏈表的節(jié)點得出總數(shù)而不是返回已計算 好的總個數(shù),這將導(dǎo)致ShrintList是一個O(n2) 的操作。

            從技術(shù)角度講,這段代碼沒有問題,也能通過所有的單元測試。但是當調(diào)用ShrintList()并傳入一個包含上億數(shù)量級的list時,它可能將 耗費數(shù)小時的時間。

            或許你會認為,這個是調(diào)用者的錯誤使用,他/她沒有認真仔細的閱讀相關(guān)的文檔!確實是這樣的,但是,事實上,這里的list.size()不是一 個恒準時(constant-time)操作,這太意外了!其他所有的C++容器類都是恒準時的size()方法呀。

            假如把size()更名成countSize()或者countElements(),類似的錯誤就會大大減少了。C++標準庫的實現(xiàn)者可能想的 是使用一個size()方法去和其他的容器匹配,像vector和map,這樣API的一致性看起來更好。正是由于這樣的做了,導(dǎo)致程序員容易誤 用并認為這是一個很快的操作,和其他的容器一樣!幸運的是,最新的C++標準要求size()是O(1)復(fù)雜度。

           

          posted on 2011-11-28 13:23 順其自然EVO 閱讀(173) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          <2011年11月>
          303112345
          6789101112
          13141516171819
          20212223242526
          27282930123
          45678910

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 青海省| 阜阳市| 大洼县| 富锦市| 永靖县| 德庆县| 绥芬河市| 广元市| 常熟市| 汝州市| 文化| 长岭县| 桐乡市| 连州市| 星座| 潍坊市| 晋宁县| 壶关县| 彩票| 阜宁县| 常熟市| 屏东县| 汾阳市| 石台县| 清丰县| 天台县| 临洮县| 凉山| 田阳县| 孝义市| 富民县| 东乌珠穆沁旗| 武隆县| 兰考县| 大理市| 浏阳市| 辽宁省| 惠来县| 洛扎县| 威海市| 磐石市|