亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

蟲蟲首頁| 資源下載| 資源專輯| 精品軟件
登錄| 注冊

您現(xiàn)在的位置是:首頁 > 技術(shù)閱讀 >  編程5分鐘,命名2小時!聊聊命名規(guī)則!

編程5分鐘,命名2小時!聊聊命名規(guī)則!

時間:2024-02-11


軟件中隨處可見命名:要給變量、函數(shù)、參數(shù)、類和封包命名,還要給源代碼及源代碼所在目錄命名,甚至還有jar文件、war文件和ear文件命名。


但是,看似簡單的命名,也是讓不少程序員頭疼的問題。有一些小伙伴,在進(jìn)行變量命名的時候,對于自己熟悉的英文,可能還會用英文命名一下,如果需要命名的部分不會用英文表達(dá),或許就直接用拼音了。


有的童鞋一下想不起來怎么命名,直接用拼音直接用aa,bb等這樣沒有任何代表意義的字母來命名,可讀性非常差,可能自己今天寫的,一個星期后回來再看,也忘記其具體代表的含義了。


因此,許多人在寫代碼之前,總會在想啊想啊,用什么命名法好呢?對于經(jīng)常在C++、Java、Python等主流語言上切換的強迫癥來說,換個語言換種命名風(fēng)格簡直不要太混亂。


既然有這么多命名要做,不妨做好它。本期內(nèi)容中,異步君為大家?guī)砹似饌€好名字應(yīng)遵從的幾條簡單規(guī)則,一起來看看吧


01

名副其實



名副其實說起來簡單。我們想要強調(diào),這事很嚴(yán)肅。選個好名字要花時間,但省下來的時間比花掉的多。注意命名,而且一旦發(fā)現(xiàn)有更好的名稱,就換掉舊的。這么做,讀你代碼的人(包括你自己)都會更開心。


變量、函數(shù)或類的名稱應(yīng)該已經(jīng)答復(fù)了所有的大問題。它該告訴你,它為什么會存在,它做什么事,應(yīng)該怎么用。如果名稱需要注釋來補充,那就不算是名副其實。

int d;  // elapsed time in days


名稱d什么也沒說明。它沒有引起讀者對時間消逝的感覺,更別說以日計了。我們應(yīng)該選擇指明了計量對象和計量單位的名稱:

int elapsedTimeInDays;int daysSinceCreation;int daysSinceModification;int fileAgeInDays;


選擇體現(xiàn)本意的名稱能讓人更容易理解和修改代碼。下列代碼的目的何在?

public List<int[]> getThem() {  List<int[]> list1 = new ArrayList<int[]>();  for (int[] x : theList)    if (x[0] == 4)      list1.add(x);  return list1;}


為什么難以說明上述代碼要做什么事?里面并沒有復(fù)雜的表達(dá)式,空格和縮進(jìn)中規(guī)中矩,只用到三個變量和兩個常量,甚至沒有涉及任何其他類或多態(tài)方法,只是(或者看起來是)一個數(shù)組的列表而已。


問題不在于代碼的簡潔度,而在于代碼的模糊度:即上下文在代碼中未被明確體現(xiàn)的程度。上述代碼要求我們了解類似以下問題的答案:

(1)theList中是什么類型的東西?

(2)theList零下標(biāo)條目的意義是什么?

(3)值4的意義是什么?

(4)我怎么使用返回的列表?


問題的答案沒體現(xiàn)在代碼段中,可代碼段就是它們該在的地方。比方說,我們在開發(fā)一種掃雷游戲,我們發(fā)現(xiàn),盤面是名為theList的單元格列表,那就將其名稱改為gameBoard。


盤面上每個單元格都用一個簡單數(shù)組表示。我們還發(fā)現(xiàn),零下標(biāo)條目是一種狀態(tài)值,而該種狀態(tài)值為4表示“已標(biāo)記”。只要改為有意義的名稱,代碼就會得到相當(dāng)程度的改進(jìn):

public List<int[]> getFlaggedCells()  {  List<int[]> flaggedCells = new ArrayList<int[]>();  for (int[] cell : gameBoard)    if (cell[STATUS_VALUE] == FLAGGED)      flaggedCells.add(cell);  return flaggedCells;}


注意,代碼的簡潔性并未被觸及。運算符和常量的數(shù)量全然保持不變,嵌套數(shù)量也全然保持不變,但代碼變得明確多了。


還可以更進(jìn)一步,不用int數(shù)組表示單元格,而是另寫一個類。該類包括一個名副其實的函數(shù)(稱為isFlagged),從而掩蓋住那個魔術(shù)數(shù)[1]。于是得到函數(shù)的新版本:

public List<Cell> getFlaggedCells()  {  List<Cell> flaggedCells = new ArrayList<Cell>();  for (Cell cell : gameBoard)    if (cell.isFlagged())      flaggedCells.add(cell);  return flaggedCells;}


只要簡單改一下名稱,就能輕易知道發(fā)生了什么。這就是選用好名稱的力量。


02

避免誤導(dǎo)



程序員必須避免留下掩藏代碼本意的錯誤線索。應(yīng)當(dāng)避免使用與本意相悖的詞,例如,hp、aix和sco都不該用作變量名,因為它們都是Unix平臺或類Unix平臺的專有名稱。即便你是在編寫三角計算程序,hp看起來是一個不錯的縮寫[2],但那也可能會提供錯誤信息。


別用accountList來指稱一組賬號,除非它真的是List類型。List一詞對程序員有特殊意義。如果包納賬號的容器并非真是一個List,就會引起錯誤的判斷。


所以,用accountGroup或bunchOfAccounts,甚至直接用accounts都會好一些。


提防使用外形相似度較高的名稱。例如,想?yún)^(qū)分模塊中某處的XYZControllerFor-EfficientHandlingOfStrings和另一處的XYZControllerForEfficientStorage-OfStrings,會花多長時間呢?這兩個詞的外形實在太相似了。


以同樣的方式拼寫出同樣的概念才是信息。拼寫前后不一致就是誤導(dǎo)。我們很享受現(xiàn)代Java編程環(huán)境的自動代碼完成特性。鍵入某個名稱的前幾個字母,按一下某個熱鍵組合(如果有的話),就能得到一列該名稱的可能形式。


假如相似的名稱依字母順序放在一起,且差異很明顯,那就會相當(dāng)有助益,因為程序員多半會壓根不看你的詳細(xì)注釋,甚至不看該類的方法列表就直接看名字挑一個對象。


誤導(dǎo)性名稱真正可怕的例子,是用小寫字母l和大寫字母O作為變量名,尤其是在組合使用的時候。當(dāng)然,問題在于它們看起來完全像是常量“壹”和“零”。

int a = l;if (O == l)  a = O1;else  l = 01;


讀者可能會認(rèn)為這純屬虛構(gòu),但我們確曾見過充斥這類名稱的代碼。有一次,代碼作者建議用不同字體寫變量名,好顯得更清楚些,但前提是這種方案得要通過口頭和書面?zhèn)鬟f給未來所有的開發(fā)者才行。后來,只是做了簡單的重命名操作,就解決了問題,而且也沒引起別的問題。


03

做有意義的區(qū)分



如果程序員只是為滿足編譯器或解釋器的需要而寫代碼,就會制造麻煩。例如,因為同一作用范圍內(nèi)兩樣不同的東西不能重名,你可能會隨手改掉其中一個的名稱,有時干脆以錯誤的拼寫充數(shù),結(jié)果就會出現(xiàn)在更正拼寫錯誤后導(dǎo)致編譯器出錯的情況。


光是添加數(shù)字系列或是廢話遠(yuǎn)遠(yuǎn)不夠,即便這足以讓編譯器滿意。如果名稱必須相異,那么其意思也應(yīng)該不同才對。


以數(shù)字系列命名(a1、a2…aN)是依義命名的對立面。這樣的名稱純屬誤導(dǎo)——完全沒有提供正確信息,沒有提供導(dǎo)向作者意圖的線索。試看:

public static void copyChars(char a1[], char a2[]) {  for (int i = 0; i < a1.length; i++) {    a2[i] = a1[i];  }}


如果參數(shù)名改為source和destination,這個函數(shù)就會像樣許多。


廢話是另一種沒意義的區(qū)分。假設(shè)你有一個Product類,如果還有一個名為ProductInfo或ProductData的類,那它們的名稱雖然不同,意思卻無區(qū)別。Info和Data就像a、an和the一樣,是意義含混的廢話。


注意,只要體現(xiàn)出有意義的區(qū)分,使用a和the這樣的前綴就沒錯。例如,你可能把a用在域內(nèi)變量,而把the用于函數(shù)參數(shù)[5]。但如果你已經(jīng)有一個名為zork的變量,又想調(diào)用一個名為theZork的變量,麻煩就來了。


廢話都是冗余。variable一詞永遠(yuǎn)不應(yīng)當(dāng)出現(xiàn)在變量名中。table一詞永遠(yuǎn)不應(yīng)當(dāng)出現(xiàn)在表名中。NameString會比Name好嗎?難道Name會是一個浮點數(shù)?如果是這樣,就違反了關(guān)于誤導(dǎo)的規(guī)則。

設(shè)想有一個名為Customer的類,還有一個名為CustomerObject的類,它們的區(qū)別何在呢?哪一個是表示客戶歷史支付情況的最佳方式?


有一個應(yīng)用反映了這種狀況。為當(dāng)事者諱,我們改了一下,不過犯錯的代碼的確就是這個樣子:


getActiveAccount(); getActiveAccounts(); getActiveAccountInfo();

程序員怎么知道該調(diào)用哪個函數(shù)呢?


如果缺少明確約定,那么變量moneyAmount與money就沒區(qū)別,customerInfo與customer沒區(qū)別,accountData與account沒區(qū)別,theMessage也與message沒區(qū)別。要區(qū)分名稱,就要以讀者能鑒別不同之處的方式來區(qū)分。


04

使用讀得出來的名稱



人類長于記憶和使用單詞。大腦的相當(dāng)一部分就是用來容納和處理單詞的。單詞能讀得出來。人類的大腦中有那么大的一塊地方用來處理言語,若不善加利用,實在是種恥辱。


如果名稱讀不出來,討論的時候就會像個傻鳥。“哎,這兒,鼻涕阿三喜摁踢(bee cee arr three cee enn tee)[6]上頭,有個皮挨死極翹(pee ess zee kyew)[7]整數(shù),看見沒?”這不是小事,因為編程本就是一種社會活動。


有一家公司,程序里面寫了一個genymdhms(生成日期,年、月、日、時、分、秒),他們一般讀作“gen why emm dee aich emm ess”[8]。我有見字照拼讀的惡習(xí),于是開口就念“gen-yah-mudda-hims”。


后來好些設(shè)計師和分析師都有樣學(xué)樣,聽起來傻乎乎的。我們知道典故,所以會覺得很搞笑。搞笑歸搞笑,實際是在強忍糟糕的命名。在給新開發(fā)者解釋變量名的意義時,他們總是讀出傻乎乎的自造詞,而非恰當(dāng)?shù)挠⒄Z詞。比較

class DtaRcrd102 {  private Date genymdhms;  private Date modymdhms;  private final String pszqint = "102";  /*  ...  */};
class Customer { private Date generationTimestamp; private Date modificationTimestamp; private final String recordId = "102"; /* ... */};


現(xiàn)在讀起來就像人話了:“喂,Mikey,看看這條記錄!生成時間戳(generation timestamp)[9]被設(shè)置為明天了!不能這樣吧?”


05

使用可搜索的名稱



對于單字母名稱和數(shù)字常量,有一個問題,就是很難在一大篇文字中找出來。


找MAX_CLASSES_PER_STUDENT很容易,但想找數(shù)字7就麻煩了,它可能是某些文件名或其他常量定義的一部分,出現(xiàn)在因不同意圖而采用的各種表達(dá)式中。如果該常量是個長數(shù)字,又被人錯改過,就會逃過搜索,從而造成錯誤。


同樣,e也不是一個便于搜索的好變量名,它是英文中最常用的字母,在每個程序、每段代碼中都有可能出現(xiàn)。由此而見,長名稱勝于短名稱,搜得到的名稱勝于用自造編碼代寫就的名稱。


竊以為單字母名稱僅用于短方法中的本地變量。名稱長短應(yīng)與其作用域大小相對應(yīng) [N5]。若變量或常量可能在代碼中多處使用,則應(yīng)賦予其便于搜索的名稱。再比較:

for (int j=0; j<34; j++) {  s += (t[j]*4)/5;}
int realDaysPerIdealDay = 4;const int WORK_DAYS_PER_WEEK = 5;int sum = 0;for (int j=0; j < NUMBER_OF_TASKS; j++) { int realTaskDays = taskEstimate[j] * realDaysPerIdealDay; int realTaskWeeks = (realTaskdays / WORK_DAYS_PER_WEEK); sum += realTaskWeeks;}


注意,上面代碼中的sum并非特別有用的名稱,不過至少搜得到它。采用能表達(dá)意圖的名稱,貌似拉長了函數(shù)代碼,但要想想看,WORK_DAYS_PER_WEEK比數(shù)字5好找得多,而列表中也只剩下了體現(xiàn)作者意圖的名稱。


06

避免使用編碼



編碼已經(jīng)太多,無謂再自找麻煩。把類型或作用域編進(jìn)名稱里面,徒然增加了解碼的負(fù)擔(dān)。沒理由要求每位新人都在弄清要應(yīng)付的代碼之外(那算是正常的),還要再搞懂另一種編碼“語言”。這對解決問題而言,純屬多余的負(fù)擔(dān)。帶編碼的名稱通常也不便發(fā)音,容易打錯。


匈牙利語標(biāo)記法


在往昔名稱長短很重要的時代,我們毫無必要地破壞了不編碼的規(guī)矩,如今后悔不迭。Fortran語言要求首字母體現(xiàn)出類型,導(dǎo)致了編碼的產(chǎn)生。BASIC語言的早期版本只允許使用一個字母再加上一位數(shù)字。匈牙利語標(biāo)記法[10](Hungarian Notation,HN)將這種態(tài)勢愈演愈烈。


在Windows的C語言API的時代,HN相當(dāng)重要,那時所有名稱要么是一個整數(shù)句柄,要么是一個長指針或者void指針,要不然就是string的幾種實現(xiàn)(有不同的用途和屬性)之一。那時候編譯器并不做類型檢查,程序員需要匈牙利語標(biāo)記法來幫助自己記住類型。


現(xiàn)代編程語言具有更豐富的類型系統(tǒng),編譯器也記得并強制使用類型。而且,程序員趨向于使用更小的類、更短的方法,好讓每個變量的定義都在視野范圍之內(nèi)。


Java程序員不需要類型編碼,因為對象是強類型的,代碼編輯環(huán)境已經(jīng)先進(jìn)到在編譯開始前就能監(jiān)測到類型錯誤的程度!所以,如今HN和其他的類型編碼形式都純屬多余。它們增加了修改變量、函數(shù)或類的名稱或類型的難度,它們增加了閱讀代碼的難度,它們制造了讓編碼系統(tǒng)誤導(dǎo)讀者的可能性。

PhoneNumber  phoneString;//  name not changed when type changed!


成員前綴


也不必用m_前綴來標(biāo)明成員變量。應(yīng)當(dāng)把類和函數(shù)做得足夠小,以消除對成員前綴的需要。你應(yīng)當(dāng)使用某種可以高亮或用顏色標(biāo)出成員的編輯環(huán)境。

public class Part {  private String m_dsc; // The textual description  void setName(String name) {    m_dsc = name;  }}--------------------------------------------------------------------------------------public class Part {  String description;  void setDescription(String description) {    this.description = description;  }}


此外,人們會很快學(xué)會無視前綴(或后綴),而只看到名稱中有意義的部分。代碼讀得越多,眼中就越?jīng)]有前綴。最終,前綴變作了不入法眼的廢料,變作了舊代碼的標(biāo)志物。


接口和實現(xiàn)


有時也會出現(xiàn)采用編碼的特殊情形。比如,你在做一個創(chuàng)建形狀用的抽象工廠(Abstract Factory),該工廠是一個接口,要用具體類來實現(xiàn)。你怎么來命名工廠和具體類呢?IShapeFactory和ShapeFactory嗎?我喜歡不加修飾的接口。前導(dǎo)字母I被濫用到了說好聽點兒是干擾,說難聽點兒根本就是廢話的程度。


我不想讓用戶知道我給他們的是接口,而就想讓他們知道那是一個ShapeFactory。如果在接口和實現(xiàn)中必須選其一來編碼的話,我寧肯選擇實現(xiàn)。ShapeFactoryImp,甚至是丑陋的CShapeFactory,都比對接口名稱編碼好。


對代碼規(guī)范感興趣的推薦本書:《代碼整潔之道》


往期推薦



shared_ptr是線程安全的嗎?

為了買房,我還特意寫了個程序

和各種詭異 Bug 打交道 13 年,我總結(jié)了 18 個經(jīng)驗

如何設(shè)計結(jié)構(gòu)體

普通的int main(){}沒有寫return 0;會怎么樣?

cout和printf,選擇哪個更好?

為什么我十分喜歡C,卻很不喜歡C++?


亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久久精品欧美丰满| 99在线精品观看| 国产精品一卡二卡| 亚洲精品一区中文| 久久婷婷综合激情| 亚洲国产小视频| 欧美大片18| 一区二区精品| 国产精品久久毛片a| 亚洲综合色视频| 国产精品美女久久久久久久| 午夜视频在线观看一区| 国产亚洲欧美一区| 牛人盗摄一区二区三区视频| 宅男噜噜噜66一区二区66| 欧美日韩精品久久久| 亚洲一二三四区| 国产亚洲女人久久久久毛片| 久久婷婷国产麻豆91天堂| 永久久久久久| 欧美日本二区| 欧美亚洲免费电影| 91久久精品国产91性色| 国产日韩欧美成人| 欧美另类一区| 麻豆精品91| 欧美伊人久久久久久午夜久久久久 | 国产欧美日本一区二区三区| 久久精品视频在线观看| 一区二区三区精品视频在线观看| 国产一区二区三区免费观看| 欧美精品在线看| 久久一区中文字幕| 亚洲一区激情| 一区二区欧美在线观看| 在线观看视频一区二区欧美日韩| 欧美午夜视频网站| 欧美国产日韩一二三区| 久久婷婷久久一区二区三区| 亚洲欧美大片| av成人动漫| 亚洲国产精品热久久| 国产日产精品一区二区三区四区的观看方式 | 亚洲高清不卡在线观看| 欧美日韩网址| 免费av成人在线| 久久精品一区二区三区中文字幕| 一区二区av在线| 亚洲电影免费观看高清| 国产精品夜夜夜| 国产精品久久久久久久7电影 | 欧美美女操人视频| 久久av二区| 亚洲欧美一级二级三级| 亚洲蜜桃精久久久久久久| 好看不卡的中文字幕| 国产精品亚发布| 国产精品久久久久久一区二区三区| 美女视频网站黄色亚洲| 欧美成人亚洲| 欧美激情一区二区三区在线视频| 久久一本综合频道| 欧美 日韩 国产在线| 欧美成人自拍| 欧美精品激情在线| 欧美日韩国产亚洲一区| 国产精品高潮在线| 国产日产高清欧美一区二区三区| 国产精品青草久久久久福利99| 国产精品超碰97尤物18| 国产精品美女久久福利网站| 国产女人水真多18毛片18精品视频| 国产精品美女诱惑| 国产精品一区二区你懂的| 国产精品有限公司| 欧美日韩国产美| 欧美激情乱人伦| 国产精品激情| 国产一区二区中文| 狠狠爱成人网| 亚洲片在线观看| 亚洲男人的天堂在线aⅴ视频| 亚洲自啪免费| 久久亚洲国产精品一区二区 | 欧美日韩国产限制| 国产精品高清在线观看| 国产欧美一区二区精品仙草咪| 国产美女一区| 91久久久久久| 亚洲一区影音先锋| 久久裸体视频| 欧美色区777第一页| 国产一区二区三区免费观看| 亚洲第一视频网站| 亚洲一区国产视频| 蜜臀va亚洲va欧美va天堂| 欧美视频四区| 亚洲第一网站| 久久精品国产一区二区三区免费看| 免费不卡中文字幕视频| 国产精品久久激情| 亚洲福利在线观看| 欧美一区二区三区精品| 欧美另类一区二区三区| 国产综合精品一区| 亚洲天天影视| 欧美精品在线一区二区| 国产在线高清精品| 亚洲影院污污.| 欧美精品在线一区二区| 国模套图日韩精品一区二区| 夜夜嗨av色一区二区不卡| 久久先锋影音av| 国产一区二区视频在线观看| 99亚洲视频| 欧美不卡高清| 激情av一区二区| 亚洲欧美日韩中文视频| 欧美成人伊人久久综合网| 国产精品福利在线| 99国产精品99久久久久久粉嫩| 久久国产精品99精品国产| 欧美日韩在线视频观看| 亚洲精品视频一区二区三区| 久久久www成人免费无遮挡大片 | 亚洲日本欧美天堂| 久久av老司机精品网站导航| 国产精品v欧美精品v日韩精品| 亚洲日本中文| 欧美成年人网站| 在线观看日韩国产| 久久久久久伊人| 国产日韩精品一区二区| 亚洲伦理一区| 欧美日韩成人在线| 亚洲免费高清视频| 乱人伦精品视频在线观看| 国内精品模特av私拍在线观看 | 国产一区欧美| 亚洲视频视频在线| 欧美日韩ab片| 中文欧美字幕免费| 欧美日在线观看| 99国产麻豆精品| 欧美日韩精品在线观看| 一区二区亚洲精品| 久久大逼视频| 国产综合第一页| 欧美一区二区三区免费视| 国产精品天天摸av网| 亚洲午夜一区二区| 国产精品二区在线| 99在线精品视频| 国产精品日韩一区| 久久精品夜色噜噜亚洲a∨| 亚洲国产视频一区二区| 欧美日韩在线播放一区| 先锋影音久久| 亚洲国产高潮在线观看| 快she精品国产999| 亚洲美女av电影| 欧美午夜精品理论片a级大开眼界 欧美午夜精品理论片a级按摩 | 久久疯狂做爰流白浆xx| 国产欧美日韩精品a在线观看| 欧美亚洲网站| 在线精品国精品国产尤物884a| 美女91精品| 91久久久精品| 欧美日韩在线视频观看| 午夜欧美大尺度福利影院在线看| 国产亚洲激情视频在线| 欧美成人综合一区| 亚洲在线免费视频| 国产一区二区三区免费观看 | 久久精品一区二区三区不卡牛牛 | 国产精品欧美日韩| 欧美一区二区在线免费观看| 黄色亚洲在线| 欧美日韩国产系列| 欧美成人日韩| 亚洲网站视频| 亚洲国产精品久久| 欧美三级免费| 欧美ab在线视频| 亚洲在线中文字幕| 国产午夜久久| 欧美日本不卡视频| 欧美在线影院| 一区二区日韩| 亚洲第一精品福利| 国产精品一二一区| 欧美韩国日本一区| 久久精品国产久精国产爱| 亚洲精品之草原avav久久| 国产欧美日韩视频| 欧美日韩成人免费| 蜜臀av一级做a爰片久久| 久久国产精品久久久久久| 亚洲精品中文字幕女同| 在线国产日韩|