目录
代码中如何做到有意义的命名
名副其实
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。这样的名称更为精确,而精确正是命名的要点。