Johnny's Collections

          生活總是有太多的無奈與失望,讓我們以在努力學習和工作中獲得的成就感和快樂來沖淡它們。

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            10 Posts :: 0 Stories :: 80 Comments :: 0 Trackbacks
          筆者從事開發多年,有這樣一種感覺,查看一些開源項目,如Spring、Apache Common等源碼是一件賞心悅目的事情,究其原因,無外兩點:1)代碼質量非常高;2)命名特別規范(這可能跟老外的英語水平有關)。
          要寫高質量的代碼,不是一件容易的事,需要長年累月的鍛煉,是一個量變到質變的過程,但要寫好命名,只需要有比較好的英語語法基礎和一種自我意識即可輕松達到。本博文將會結合本人的開發經驗,總結出若干命名規則,這些命名規則純屬個人的使用習慣,不代表是一種理想的規則,在這里列舉出來,供大家交流討論。

          1.切忌使用沒有任何意義的英語字母進行命名:
              for(int i=0; i<10; i++) {
                  ...
              }
          這是在很多教Java基本語法的書上常見的代碼片斷,作為教學材料,這樣寫無可厚非,但作為真正的代碼編寫,程序員必須要養成良好的習慣,不要使用這種沒有任何含義的命名方式,這里可以使用“index”。

          2.切忌使用拼音,甚至是拼音首字母組合:
              cishu =5; // 循環的次數
              zzje = 1000.00 // 轉賬金額
          筆者在做代碼檢查的時候,無數次遇到過這樣的命名,使人哭笑不得

          3.要使用英文,而且要使用準確的英語,無論是拼寫還是語法:
          • 名詞單數,必須使用單數英文,如Account、Customer。
          • 對于數組,列表等對象集合的命名,必須使用復數,而且最好按照英文的語法基礎知識使用準確的復數形式,如 List<Account> accounts、Set<Strategy> strategies。
          • 對于boolean值的屬性,很多開發人員習慣使用isXXX,如isClose(是否關閉),但這里有兩點建議:1)最好不要帶“is”,因為JavaBean的規范,為屬性生成get/set方法的時候,會用“get/set/is”,上面的例子,生成get/set方法就會變成“getIsClose/isIsClose/getIsClose”,非常別扭;2)由于boolean值通常反映“是否”,所以準確的用法,應該是是用“形容詞”,上面的例子,最終應該被改為 closed,那么get/set方法就是“getClosed/isColsed/setClosed”,非常符合英語閱讀習慣。

          4.方法名的命名,需要使用“動賓結構短語”或“是動詞+表語結構短語”,筆者曾看到過千奇百怪的方法命名,有些使用名詞,有些甚至是“名詞+動詞”,而且,如果賓語是一個對象集合,還是最好使用復數:
              createOrder(Order order) good   
              orderCreate(Order order) bad
              removeOrders(List<Order> orders) good
              removeOrder(List<Order> order) bad

          5.對于常見的“增刪改查”方法,命名最好要謹慎:
          • 增加:最常見使用create和add,但最好根據英語的語義進行區分,這有助于理解,create代表創建,add代表增加。比如,要創建一個Student,用createStudent要比用addStudent好,為什么?想想如果有個類叫Clazz(班級,避開Java關鍵字),現在要把一個Student加入到一個Clazz,Clazz很容易就定義了一個 addStudent(Student student)的方法,那么就比較容易混淆。
          • 修改:常見的有alter、update、modify,個人覺得modify最準確。
          • 查詢:對于獲取單個對象,可以用get或load,但個人建議用get,解釋請見第7點的說明,對于不分條件列舉,用list,對于有條件查詢,用search(最好不要用find,find在英文了強調結果,是“找到”的意思,你提供一個“查詢”方法,不保證輸入的條件總能“找到”結果)。
          • 刪除:常見的有delete和remove,但刪除建議用delete,因為remove有“移除”的意思,參考Clazz的例子就可以理解,從班級移除一個學生,會用removeStudent。

          6.寧愿方法名冗長,也不要使用讓人費解的簡寫,筆者曾經遇到一個方法,判斷“支付賬戶是否與收款賬戶相同”,結果我看到一個這樣的命名:
              checkIsOrderingAccCollAccSame(...) 很難理解,我馬上把它改為:
              isOrderingAccountSameAsCollectionAccount(...),雖然有點長,但非常容易閱讀,而且這種情況總是出現得比較少。

          7.如果你在設計業務系統,最好不要使用技術化的術語去命名。筆者曾經工作的公司曾經制訂這樣的命名規則,接口必須要以“I”開頭,數據傳輸對象必須以“DTO”作為后綴,數據訪問對象必須以“DAO”作為后綴,領域對象必須以“DO”作為后綴,我之所以不建議這種做法,是希望設計人員從一開始就引導開發人員,要從“業務”出發考慮問題,而不要從“技術”出發。所以,接口不需要非得以“I”開頭,只要其實現類以“Impl”結尾即可(注:筆者認為接口是與細節無關的,與技術無關,但實現類是實現相關的,用技術化術語無可口非),而數據傳輸對象,其實無非就是保存一個對象的信息,因此可以用“**Info”,如CustomerInfo,領域對象本身就是業務的核心,所以還是以其真實名稱出現,比如Account、Customer,至于“DAO”,這一個詞來源于J2ee的設計模式,筆者在之前的項目使用“***Repository”命名,意味“***的倉庫”,如AccountRepository,關于“Repository”這個詞的命名,是來源于Eric Evans的《Domain-Driven Design》一書的倉庫概念,Eric Evans對Repository的概念定義是:領域對象的概念性集合,個人認為這個命名非常的貼切,它讓程序員完全從技術的思維中擺脫出來,站在業務的角度思考問題。說到這里,可能有人會反駁:像Spring、Hibernate這些優秀的框架,不是都在用“I”作為接口開頭,用“DAO”來命名數據訪問對象嗎?沒錯!但千萬別忽略了語義的上下文,Spring、Hibernate框架都是純技術框架,我這里所說的場景是設計業務系統。

          8.成員變量不要重復類的名稱,例如,很多人喜歡在Account對象的成員變量中使用accountId,accountNumber等命名,其實沒有必要,想想成員變量不會鼓孤立的存在,你引用accountId,必須是account.accountId,用account.id已經足夠清晰了。

          “勿以善小而不為,勿以惡小而為之”、“細節決定成敗”,有太多的名言告訴我們,要注重細節。一個優秀的程序員,必須要有堅實的基礎,而對于命名規則這樣容易掌握的基礎,我們何不現行?
          posted on 2010-04-29 22:54 Johnny.Liang 閱讀(6610) 評論(17)  編輯  收藏 所屬分類: 編程技巧

          Feedback

          # re: 編寫高質量的代碼——從命名入手[未登錄] 2010-04-30 10:35 m
          第一個就寫爆了……
          for語句內使用i,j,k……是約定俗成的,符合習慣的。
          并不是說教材上胡亂寫的。  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2010-04-30 11:35 BioKen
          第一個是有點牽強,可能他所舉的例子不能表達的真正想要表達的意思吧@m
            回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2010-04-30 11:52 泰妮絲童裝
          按開始的開始就愛看的  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2010-04-30 12:27 BearRui(AK-47)
          其實一直有個想法困難很久,為什么不能使用拼音,大家都是中國人,英語水平參差不齊,但拼音水平還是一樣的,而且用英文同1個意思,不同人寫出來單詞確不一樣。我覺得使用拼音非常好,在注釋比較少的情況下,拼音命名更能幫助理解程序。個人覺得拼音更加適合我們的國情。

          當然如果非常常見的除外,比如add,insert delete。

          如果你寫的程序會給外國人看哪就另當別人認了。可是有幾個人的代碼會給外國人看?  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2010-04-30 12:45 Johnny.Liang
          @BearRui(AK-47)
          我是這樣想的,做開發人員,基礎英語知識是必備的工具,很多技術文檔、規范、API都是英文的,即使有翻譯,也是讀英語的比較好,因此在我參與過的項目中,包括我曾經工作過的公司,都是嚴禁使用拼音的。  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手[未登錄] 2010-05-01 19:56 海邊沫沫
          用拼音是真的不好,因為你不能把1234聲注上去,而且即使注上去了,也有很多重復的詞。用純拼音寫一本書你看不看?

          用拼音的縮寫就更加要人命了。

          樓主的總結非常好,特別是對boolean變量的命名,讓我很受啟發。其它的條目我一般都是和樓主一樣的做法。  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2010-05-02 11:10 vagrant
          政府項目里面,無數的中國特色式業務名稱,怎么翻譯成英文?項目組一堆人,怎么確保同一個名稱翻譯成同一個英文單詞?  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2010-05-04 18:21 sf
          第一項就亂叫,請去看下linux 內核源碼在來寫blog, ok?  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2010-05-06 10:29 r
          @vagrant
          世事無絕對,樓主概括的是大部分的情況。頂樓主一個,辛苦!
            回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手[未登錄] 2010-05-07 17:41 Gavin
          值得借鑒...  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手[未登錄] 2010-05-21 09:28 Mike
          寫得不錯,感謝樓主分享。 期待有更多高質量的文章可以學習。  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2010-06-20 15:22 趙云
          第一項不敢恭維!  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2011-01-05 17:55 Xluo
          贊一個,學習了。  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2012-10-15 22:17 eyougo
          當你遇到
          JYR
          JYRQ
          JYRS
          YYRQ
          YYR
          這一長串變量命名在一個類里的時候,頭疼不?
          解釋一下:
          JYR借閱人
          JYRQ借閱日期
          JYRS借閱人數
          YYRQ預約日期
          YYR預約人
          哈哈哈  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2014-06-30 12:57 dohkoos
          第1點完全是謬論,約定俗成的東西你也要改。而且你以為人家不寫成index是沒有理由的嗎??
          for (int i = 0; i < n; i++) {
          for (int j = 0; j < i; j++) {
          }
          }
          算法里經常有這種代碼,你把 j 這個變量改改看,腦細胞死一堆還可能找不到更好的命名。那些寫程序的先驅幾年幾十年的血淚總結出來的東西啊。

          為什么不可以在代碼中使用拼音命名。代碼可讀性包含一致性,因為基礎代碼都是英文的,如果用拼音命名的話,就破壞了這點,破壞了代碼的可讀性。在讀代碼時需要頻繁地在命名是拼音還是英文中切換,影響效率。
          用首字母縮寫??過段時間你自己還能記得它是什么意思??  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2015-05-28 18:15 會長
          1,第一個是約定成俗了,而且我一直認為i是index的縮寫;
          2,拼音或漢字我覺得可以偶爾使用,有些詞很難翻譯,如”計劃生育“、”改革開放“等;
          3,接口I打頭,抽象類Abs打頭一目了然,”實現類以“Impl”結尾“,不也是從技術的角度出發的,如果實現類還實現了別的接口怎么辦...
          4,"成員變量不要重復類的名稱",這樣的話如果數據庫中字段名稱為XXXId,那么實體類屬性名稱與之對應比較好。當然數據庫也可以不加XXX,直接上Id,但我覺得主鍵還是tableNameId比較好,否則在長SQL語句中到處都是Id,眼花繚亂。

          其余部分嚴重同意。  回復  更多評論
            

          # re: 編寫高質量的代碼——從命名入手 2015-05-28 18:18 會長
          @BearRui(AK-47)
          拼音的話會產生歧義。當然熟悉系統的人沒事,新人就比較郁悶了,想砸鍵盤。  回復  更多評論
            


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


          網站導航:
           
          主站蜘蛛池模板: 天峨县| 咸阳市| 宿松县| 青岛市| 正蓝旗| 闸北区| 隆回县| 清远市| 宁陵县| 大新县| 富蕴县| 团风县| 灌阳县| 象州县| 通城县| 新绛县| 鲁甸县| 海城市| 弥勒县| 长春市| 太白县| 西青区| 宜都市| 清镇市| 赣榆县| 东兴市| 德令哈市| 芜湖县| 梧州市| 托里县| 西乌珠穆沁旗| 兰考县| 红原县| 新源县| 金平| 高邑县| 乌什县| 太谷县| 同仁县| 田林县| 当阳市|