目錄
代碼中如何做到有意義的命名
名副其實
int elapsedTimesInDays;//消逝的時間
避免誤導
避免使用與本意相悖的詞
- 不使用平臺專有名稱
- 不使用accountList代表一組賬號。List會引起錯誤的判斷,可以使用accountGroup、accounts。
- 提防使用不同之處較小的名稱。如XYZControllerEffientHandlingOfStrings和XYZControllerEffientStorageOfStrings
做有意義的區分
Product、ProductInfo、ProductData,雖然名稱不同,意思卻無區別。
使用讀得出來的名稱
讀不出來的名稱:
- genymdhms
- modymdhms
讀得出來的名稱:
- generationTimestam
- modificationTimestamp
使用可搜索的名稱
不可搜索的名稱
for(int j=0;j<34;j++)
{
s += (t[j]*4)/5;
}
可搜索的名稱
int realDayPerIdealDay = 4;
const int WORK_DAYS_PER_WEEK = 5;
int sum = 0;
for(int j=0;j < NUMBERS_OF_TASKS;j++)
{
int realTasksDays = taskEstimate[j] * realDayPerIdealDay;
int realTasksWeeks = (realTasksDays / WORK_DAYS_PER_WEEK);
sum += realTasksWeeks;
}
避免使用編碼
匈牙利語標記法
在windows的C語言APi時代,HN相當重要,編譯器並不做類型檢查,程序員需要匈牙利語標記法來幫助自己記住類型。
現代編程語,如Java、C#不需要類型編碼。對象是強類型的,代碼編輯環境已經先進到在編譯開始前就偵測到類型錯誤的程序。所以如今HN和其他類型的編碼形式純屬多餘。
成員前綴
不必使用m_前綴代表成員變量。應當把類和函數做的足夠小。
class Part
{
private string m_dsc;
}
class Part
{
private string description;
}
接口和實現
IShapeFactory和ShapeFactory對應接口和接口實現類。
避免思維映射
不應當讓讀者在腦中把你的名稱翻譯爲他們熟知的名稱。這種問題經常出現在選擇是使用問題領域術語還解決方案領域術語。
專業程序員瞭解,明確是王道。專業程序員善用其能,編寫其他人能理解的代碼。
類名
類名和對象應爲名詞或名詞短語。如Customer、Account、AddressParser。避免使用Manager、Processor、Data、Info這樣的類名。類名不應當是動詞。
方法名
方法名應爲動詞或動詞短語。如postPayment、deletePage。
重載構造器時,使用描述了參數的靜態工程命名通常好於使用new關鍵字。
Complex fullcrumPoint = Complex.FromRealNumber(23.0);
Complex fullcrumPoint = new Complex(23.0);
別扮可愛
言到意到。意到言到
- 不耍寶——類似於"HolyHandGrenade(聖手手雷)"就是耍寶的名稱,DeleteItem是更好的名稱。
- 不使用俗語或俚語——別用whack()代替kill()。
每個概念對應一個詞
比如在一堆代碼中有controller,又有manager,還有driver,就會令人疑惑。這種名稱,讓人覺得這兩個對象是不同類型,也分數不同的類。
別用雙關語
避免將同一單詞用於不同目的。同一術語用於不同概念,基本上就是雙關語了。如,在多個類都有add方法,該方法通過增加或連接兩個現存值來獲得新值。假設要寫個新類,該類有一個方法,把單個參數放到(collection)中。該方法叫做add嗎?這樣做貌似和其他add方法保持了一致,但實際上語義不同。應該用insert或append之類的詞來命名纔對。
使用解決方案領域名稱
只有程序員纔會讀代碼。所以,儘管用那些計算機科學術語、算法名、模式名、數學術語把。對於熟悉訪問者(VISITOR)模式的程序來說,名稱AccountVisitor富有意義。哪個程序員會不知道JobQueue的意思呢?
使用源自所涉問題領域的名稱
如果不能用程序員熟悉的術語來給手頭的工作命名,就採用從所涉問題領域而來的名稱吧。至少,負責維護代碼的程序員就能去請教領域專家了。
優秀的程序員和設計師,其工作之一就是分離解決方案領域和問題領域的概念。與所涉問題領域更爲貼近的代碼,應當採用源自問題領域的名稱。
添加有意義的語境
大多數的名稱是不能自我說明的。需要用有良好命名的類、函數或命名空間來放置名稱,給讀者提供語境。如沒這麼做,給名稱添加前綴就是最後一招了。
如果有名爲firstName、lastName、street、houseNumber、city、state和zipcode的變量。當它們放在一起時,很明確是構式了一個地址。不過,假使只是在某個方法中看到單個state變量呢?會認爲是某個地址的一部分嗎?
可以添加前綴addrFirstName、addrLastNatne、addrState等,以此提供語境。當然,更好的方案是創建名爲Address的類。
語境不明確的變量:
private static void PrintGuessStatistics(char candidate, int count)
{
string number;
string verb;
string pluralModifier;
if (count == 0)
{
number = "no";
verb = "are";
pluralModifier = "";
}
else if (count == 1)
{
number = "1";
verb = "is";
pluralModifier = "";
}
else
{
number = count.ToString();
verb = "are";
pluralModifier = "s";
}
string guessMessage = string.Format("There {0} {1} {2}{3}", verb, number, candidate, pluralModifier);
Console.WriteLine(guessMessage);
}
有語境的變量
public class GuessStstisticMessage
{
private string number;
private string verb;
private string pluralModifier;
public string Make(char candidate, int count)
{
createPluarlDependentMeaasge(count);
return string.Format("There {0} {1} {2}{3}", verb, number, candidate, pluralModifier);
}
private void createPluarlDependentMeaasge(int count)
{
if (count == 0)
{
ThereAreNoLetters();
}
else if (count == 1)
{
ThereIsOneLetter();
}
else
{
ThereAreManyLetters(count);
}
}
private void ThereAreManyLetters(int count)
{
number = count.ToString();
verb = "are";
pluralModifier = "s";
}
private void ThereIsOneLetter()
{
number = "1";
verb = "is";
pluralModifier = "";
}
private void ThereAreNoLetters()
{
number = "no";
verb = "are";
pluralModifier = "";
}
}
不要添加沒用的語境
假設有一個名爲“加油站豪華版”(Gas Station Deluxe)的應用,在其中給每個類添加GSD前綴就不是什麼好點子。輸入G得到全部類的列表,列表恨不得有一英里那麼長。這樣IDE就沒有辦法幫助你。
在比如,在GSD的記賬模塊創建了一個表示郵件地址的類,然後給該類命名爲GSDAccountAddress。稍後,當你使用GSDAccountAddress時,在這17個字母裏面,有10個字母純屬多餘且與當前語境毫無關聯。
只要短名稱足夠清楚,就要比長名稱好。別給名稱添加不必要的語境。
對於Address類的實體來說,accountAddress和customerAddress都是不錯的名稱,不過用在類名上就不太好了。Address是個好類名。如果需要與MAC地址、端口地址和Web地址相區別,建議使用PostalAddress、MAC和URI。這樣的名稱更爲精確,而精確正是命名的要點。