前幾天Neo寫過《編程中的命名設(shè)計那點事》,這里也有另外一篇和程序命名的文章,可以從另一個角度看看。
1.- 變量應(yīng)該是盡可能的望文知意。千萬不要使用教材中的命名方式。
- 好的變量: daysDateRange, flightNumber, carColor.
- 壞的變量: days, dRange, temp, data, aux…
在我們的日常工作中,有很大數(shù)量的開發(fā)人員喜歡使用短的變量名,而不是有含義的變量名。這主要是因為我們大學教科書的那些示例所造成的,人都是先入為主,所以,教科書中的那些很抽象,帶著演示的變量命名影響了我們一代又一代的程序員,并影響了他們很多年。雖然那些短的,教材式的變量名,可能會讓你少打一些字,但其實,這是非常非常不好的。因為軟件的維護成本遠遠大于了軟件的開發(fā)成本,如果你不取一個好的一點的變量名,那么當進行代碼評審時,當進行bugfixing時,當進行代碼重構(gòu)時,當進行代碼維護時,你的某個變量名可能會讓你一頭霧水,不知道所措,還可以會讓你走入陷阱,造成更大的時間成本。所以,一個可閱讀的代碼必然和那些不錯的變量名分不開,而這也能讓你的軟件間接上有更好的質(zhì)量。
2.- 變量名不要太長,盡可能地簡短
只有簡單和簡短的變量名才是容易閱讀的。因為你的變量名一定會用于程序語句中,所以,為了讓你的程序語句看起來的簡短,你的變量名也應(yīng)該短一點,不然寫出來的一個表達式就會顯得很復雜。
當然,在有些時候,一個有含義的變量名和一個簡短的變量名可能存在一些沖突。這相當鍛煉我們的語言能力——如果有最精煉的詞語來表達最豐富的含義。如果實在做不到,那么,取一個有含義的變量名要比取一個簡短的變量名更好一些。不管怎么樣,我們希望即簡短又有豐富的含義,但如果不能兩全,那有含義優(yōu)先級更高一些。
- 壞的變量:howLonDoesItTakeToOpenTheDoor, howBigIsTheMaterial…
- 好的變量:timeToOpenTheDoor, MaterialSize.
3.- 可以使用縮寫,但需要有一些注釋
有一些時候,我們需要使用一些縮寫來命名變量,比如:用usr來表示user,用gp來表示group,用conf來表示configuration,用cwd來表示current working directory,用ptr來代碼point toreference,等等,等等??s寫一般要用在大家可以看得懂的,而不是為了縮寫而縮短一個單詞,當然,如果你把縮寫后的變量名加上注釋,那就更加穩(wěn)妥了。關(guān)于一些約定俗成的縮寫,可參看本文的附錄一。
4.- 使用合適的匈牙利命名規(guī)則
這里有一篇非常不錯的英文文章告訴你 《什么是合適的匈牙利命名 》,這篇文章同時還告訴你如何去用他?;旧蟻碚f,匈牙利命名法主要是為變量加上某種前綴以標識這個變量的類型,或是一種方法的功能。其基本原則是:變量名=屬性+類型+對象描述。
比如:在描述類型方面:指針p,函數(shù)fn,長整型 l,布爾b,浮點型(有時也指文件)f,雙字 dw,字符串 sz,短整型 n,雙精度浮點 d,無符號 u……等等。關(guān)于更多的命名規(guī)范,請參見附錄二。
注意,匈牙利命名也是有不好的地方的,比如你要把一個整形改成一個浮點型,你除了要改變這個變量的類型,你還要改變這個變量的名字。這是相當麻煩的。而且,在某些時候,這種前綴式的命名可以反而讓你不知所措。另外,在C++中,有了類以后,這種命名方法就顯得不容易去實施了。所以,合適地使用匈牙利命名方式背后的思想是很關(guān)鍵的。
5.- 不要使用反邏輯來命名
- 好的命名: IsEnabled.
- 壞的命名: IsNotEnabled.
在閱讀的時候,我們更喜歡正向的邏輯,而不是反向邏輯。這一規(guī)則不單單的命名,在條件語句中,我們也是要盡量不要使用這種反面的邏輯。如:if(! (isAdmin || isUser)),這樣的語句很不符合人讀代碼的習慣,寫成這樣會更好一些——if (!isAdmin&& !isUser)。
6.- 保持一致性
保持所有代碼的一致性。使用相同的命名規(guī)則。這外世界上沒有最好的命名規(guī)范。但有一點是可以確認的,那就是在一個代碼庫中,應(yīng)該使用一致的命名規(guī)則,即使這個規(guī)則不那么好,但整個團隊使用一致的就是好的。
7.- 附和應(yīng)用程序的領(lǐng)域術(shù)語
在不同的領(lǐng)域中,不同的觀念會有非常特別和不同的意思。例如:單詞“order”并不總是意味著“次順”,有些時候,其意味著“訂單”,有些時候,意味著“命令”,有些時候,意為著“規(guī)則”。所以,在某個領(lǐng)域中,某些單詞會有不同的含義,所以,這需要我們的命令去附和這些領(lǐng)域。
黃金法則- 花一些時間去思考去權(quán)衡一下你的變量名
當你設(shè)計好一個的變量名一個函數(shù)名的時候,別著急去使用他,停下來,想一想,這個變量名是否合適,是否還有更好的?也許你正在使用的是一個很不好的變量名。有些時候,需要我們權(quán)衡利弊一下,可能還要去和同事討論一下。
總之,變量名是編程的第一步,第一步走好了,后面才走得好。試想,無論是你或你的同事在使用一些好的變量名編程是一件多么輕松的事啊。
附錄:部分的縮寫規(guī)范
完整單詞 | 縮寫 |
A | |
average | avg |
B | |
back | bk |
background | bg |
break | brk |
buffer | buf |
C | |
color | cr,clr |
control | ctrl |
D | |
data | dat |
delete | del |
document | doc |
E | |
edit | edt |
error | err |
escape | esc |
F | |
flag | flg |
form | frm |
G | |
grid | grd |
I | |
increment | inc |
information | info |
initial | init |
insert | ins |
image | img |
L | |
lable | lab |
length | len |
list | lst |
library | lib |
M | |
manager | mgr,mngr |
message | msg |
O | |
Oracle | Ora |
P | |
panorama | pano |
password | pwd |
picture | pic |
point | pt |
position | pos |
prn | |
program | prg |
S | |
server | srv |
source | src |
statistic | stat |
string | str |
Sybase | Syb |
T | |
temp | tmp |
text | txt |
U | |
user | usr |
W | |
window | win,wnd |
附錄二、匈牙利命名法
a Array 數(shù)組b BOOL (int) 布爾(整數(shù))by Unsigned Char (Byte) 無符號字符(字節(jié))c Char 字符(字節(jié))cb Count of bytes 字節(jié)數(shù)cr Color reference value 顏色(參考)值cx Count of x (Short) x的集合(短整數(shù))dw DWORD (unsigned long) 雙字(無符號長整數(shù))f Flags 標志(一般是有多位的數(shù)值)fn Function 函數(shù)g_ global 全局的h Handle 句柄i Integer 整數(shù)l Long 長整數(shù)lp Long pointer 長指針m_ Data member of a class 一個類的數(shù)據(jù)成員n Short int 短整數(shù)p Pointer 指針s String 字符串sz Zero terminated String 以0結(jié)尾的字符串tm Text metric 文本規(guī)則u Unsigned int 無符號整數(shù)ul Unsigned long (ULONG) 無符號長整數(shù)w WORD (unsigned short) 無符號短整數(shù)x,y x, y coordinates (short) 坐標值/短整數(shù)v void 空
有關(guān)項目的全局變量用g_開始,類成員變量用m_,局部變量若函數(shù)較大則可考慮用l_用以顯示說明其是局部變量。
前綴 類型 例子g_ 全局變量 g_ServersC 類或者結(jié)構(gòu)體 CDocument,CPrintInfom_ 成員變量 m_pDoc,m_nCustomers
VC常用前綴列表:
前綴 類型 描述 例子ch char 8位字符 chGradech TCHAR 16位UNICODE類型字符 chNameb BOOL 布爾變量 bEnabledn int 整型 nLengthn UINT 無符號整型 nLengthw WORD 16位無符號整型 wPosl LONG 32位有符號整型 lOffsetdw DWORD 32位無符號整型 dwRangep * 內(nèi)存模塊指針,指針變量 pDoclp FAR* 長指針 lpDoclpsz LPSTR 32位字符串指針 lpszNamelpsz LPCSTR 32位常量字符串指針 lpszNamelpsz LPCTSTR 32位UNICODE類型常量指針 lpszNameh handle Windows對象句柄 hWndlpfn (*fn)() 回調(diào)函數(shù)指針 lpfnAbort
Windows對象名稱縮寫:
Windows對象 例子變量 MFC類 例子對象HWND hWnd; CWnd* pWnd;HDLG hDlg; CDialog* pDlg;HDC hDC; CDC* pDC;HGDIOBJ hGdiObj; CGdiObject* pGdiObj;HPEN hPen; CPen* pPen;HBRUSH hBrush; CBrush* pBrush;HFONT hFont; CFont* pFont;HBITMAP hBitmap; CBitmap* pBitmap;HPALETTE hPalette; CPalette* pPalette;HRGN hRgn; CRgn* pRgn;HMENU hMenu; CMenu* pMenu;HWND hCtl; CStatic* pStatic;HWND hCtl; CButton* pBtn;HWND hCtl; CEdit* pEdit;HWND hCtl; CListBox* pListBox;HWND hCtl; CComboBox* pComboBox;(全文完)