如何給程序中的變量起個好名字

>>>  技術話題—商業文明的嶄新時代  >>> 簡體     傳統

愛編程,不愛修電腦;愛學習,更愛運動;愛科技,也愛娛樂;愛工作,不愛加班。愛幽默、愛生活、愛浪漫、愛打拼,我是程序員,我為自己代言,關注程序員,分享程序員的那些事兒!


新手程序員總是把大量的時間用在學習編程語言上,學習語法,技術和開發工具,他們認為如果掌握了這些就是一個優秀的程序員。但是,實際的編程不僅是要精通技術和工具,關鍵是要對某個特定領域的問題給出解決方案,而且通常要和其他程序員一起合作完成。因此,很重要的一點就是,程序員要用代碼準確的表達出自己的思想,從而讓其他人明白程序的含義。


編程大師Robert C. Martin在《Clean Code》中說道:“使用注釋是為了彌補我們代碼表意上的不足。”這句話就意味著如果你的代碼需要添加注釋,就說明你的代碼還不夠好。同時,這也說明如果不能在單純的代碼中展示你對問題或算法的理解是非常失敗的,你只能依靠一些注釋說明你的想法,而不能僅用代碼顯示。優秀的代碼可以讓人在沒有注釋的情況下看懂并理解,好的編程習慣也是讓所有必要的信息都在代碼中展示出來。


在編程理論中,有一個概念叫做“可以自我描述的源代碼”,尤其是在那些有著較松的命名規則的環境下。引入這個概念,就是要增加代碼的可讀性,使代碼更容易被維護和擴展。


下面我會對比一些“好的代碼”和“不清晰的代碼”。


命名時要展現你意圖


如何在代碼中命名一直是一個問題,一些程序員總是用簡化,短小或編碼后的名字,使得只有他們自己才能看懂。看一些例子:

不好的代碼:
int d; //elapsed time in days
int ds;
int dsm;
int faid;

名字中“d”可以表示任何東西,程序員只能用注釋來表明他的意圖,不能僅用代碼顯示。而“faid”很容易導致誤解為ID。

清晰的代碼:

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

避免會被誤解的命名


導致誤解的信息比沒有信息更糟糕,有些程序員喜歡“隱藏”一些重要信息,但更糟的是,他們有時會寫出一些讓人誤解的代碼。

不好的代碼:
Customer[] customerList;
Table theTable;

變量“customerList”其實不是個list。它只是一個普通的數組(集合)。第二行中,“theTable”是一個Table類的對象,“the”這個詞是個不必要的干擾。

清晰的代碼:
Customer[] customers;
Table customers;

適合的名字長度


在現代的編程語言中,很長的變量名字是被允許的,你可以基本不受限制的去命名,但是這樣會導致命名的混亂。

不好的代碼:
var theCustomersListWithAllCustomersIncludedWithoutFiler;
var list;

好的名字應該包含足夠的單詞來表達意思,但是任何不必要的詞都會使名字變長,變得難以理解。名稱越短越好,前提是能在上下文中表達完整的意思。

清晰的代碼:
var allCustomers;
var customersInOrder;

符合“代碼規范”,可以更好的幫助理解


所有的編程語言都有自己的“風格”,叫做表示法。程序員應該寫出符合這種表示法的代碼,因為其他的程序員也知道這點,并按這種風格寫程序。我們來看一個不符合表示法的不好的代碼例子。下面的這段代碼沒有遵循任何代碼標準(比如PascalCase, camelCase, Hungarian規范)。更糟糕的是,這里有一個無意義的bool型變量change,這是個描述動作的動詞,但這里的bool值應該表示一種狀態,所以這個變量應該用一個形容詞來命名。

不好的代碼:
const  int maxcount = 1;
bool  change = true;

public  interface Repository;
private  string Name;
public  class personaddress;

void  getallorders();

因為代碼規范,當你只看一部分代碼時,你就可以理解這里面的變量類型和含義,比如,你看到一個變量“_name”,你就可以知道這是當前類中的一個私有變量。所以,你寫出的任何代碼都要遵從規范。

清晰的代碼:
const  int MAXCOUNT = 1;
bool  isChanged = true;

public  interface IRepository;
private  string _name;
public  class PersonAddress;

void  GetAllOrders();

一個概念不要用多種詞表示,一個詞也不要表示多種概念


定義場景中的概念很難,在軟件開發過程中,程序員需要花費很多時間去分析某一場景,并命名場景中的各種元素,這樣的工作永遠都是讓程序員頭疼的事情。

不好的代碼:

//1.

void  LoadSingleData();
void  FetchDataFiltered();
void  GeteAllData();

//2.
void  SetDataToView();
void  SetObjectValue(int value);

在第一段代碼中,這個程序員想表達“獲取數據”這個概念,但他用了很多不同的詞”load”,”fetch”,”get”。在一個場景下,應該用一個統一的詞表示這個概念。在第二段代碼中,”set”一詞被用作了兩個概念,第一個是“取出數據顯示”,第二個是“為一個對象賦值”,應該用不同的詞表示這兩個不同的概念。

清晰的代碼:

//1.

void  GetSingleData();
void  GetDataFiltered();
void  GetAllData();

//2.

void  LoadDataToView();
void  SetObjectValue(int value);

使用某一領域背景中有意義的名字


程序員寫的所有代碼都是和某一領域背景相關的,為了讓寫出的代碼可以讓個更多的人理解,最好使用該領域背景下的名字。

不好的代碼:

public class  EntitiesRelation

{
Entity o1;

Entity o2;

}

當你在編寫針對某個領域的代碼時,你應該使用領域背景相關的名字。如果以后有另外的人(不僅是程序員,也許是測試人員)接觸你的代碼時,他能輕松的理解你與背景相關的代碼。所以,程序員首先應該考慮的是領域背景問題,之后才是如何得出解決方案。

清晰的代碼:

public class  ProductWithCategory

{
Entity product;

Entity category;

}

使用上下文環境下有意義的名字


代碼里的名字都有自己的上下文,上下文對于理解一個代碼是很重要的,因為它能提供額外的信息。我們來看一個典型的“地址”上下文:

不好的代碼:

string addressCity;

string addressHomeNumber;

string addressPostCode;

在大多數情況中,“郵政編碼”(PostCode)是地址的一部分,很顯然,郵政編碼不能單獨使用(除非你是在開發一個專門處理郵編的應用)。所以,沒有必要在“PostCode”的前面加上“address”。而且,所有的這些信息都應該有一個上下文環境,在面向對象編程中,這里應該用一個“Address”類來表達這個地址信息。

清晰的代碼:

class Address

{

string city;

string homeNumber;

string postcode;

}

總結


總結一下,作為一名程序員,你應該:


1.起的名字是有意義的,可以表達一個概念;


2.要考慮名字的長度,名稱中只有必要的信息;


3.符合“編碼規范”,幫助理解;


4.一個概念不要多種名字混用;


5.使用在背景領域和上下文中都有意義的名字。




CocoaChina 2015-08-23 08:45:07

[新一篇] 【趨勢】2015年,最有賺錢潛力的十大行業 ...

[舊一篇] 程序猿的故事,看罷不禁捂緊胸口。。。
回頂部
寫評論


評論集


暫無評論。

稱謂:

内容:

驗證:


返回列表