代码整洁之道 — 1 命名规范
目录
1.1 不同数据类型命名规范
1.2 名副其实
1.3 避免误导
1.4 有意义的区分
1.5 使用读得出来的名称
1.6 使用可搜索的名称
1.7 避免过度使用编码
1.8 使用专业领域的名称
1.1 不同数据类型命名规范
编程中不同数据的命名规范提高了代码的可读性和一致性。例如,常量和宏定义使用全大写字母,变量和函数采用小驼峰式,而结构体和枚举类型名则使用大驼峰式,这样的区分有助于识别代码中的不同元素。
类型 | 规范 | 示例 | |
常量名 | 全大写,单词间用下划线分隔 | MAX_CLASSES_PER_STUDENT | |
变量名 | 小驼峰式(首单词小写,后续单词首字母大写) | studentCount | |
函数名 | 小驼峰式(同变量名) | calculateTotalScore | |
结构体名 | 大驼峰式(所有单词首字母大写) | StudentRecord | |
联合体名 | 大驼峰式(同结构体名) | GeometryShape | |
枚举类型名 | 大驼峰式(同结构体名) | Weekday | |
宏定义 | 全大写,单词间用下划线分隔 | PI | |
全局变量 | 小驼峰式或下划线分隔小写 | globalConfig 或 global_config | |
静态变量 | 小驼峰式或下划线分隔小写 | staticCounter 或 static_counter | |
类型定义 | 大驼峰式 | MyCustomType | |
类型前缀 | 根据类型使用特定前缀 | g_ 用于全局变量,s_ 用于静态变量 | |
枚举成员 | 大写,单词间用下划线分隔 | RED_COLOR | |
类名 | 名词或名词短语,避免使用Manager、Processor、Data或Info等动词 | Customer, Account | |
方法名 | 动词或动词短语 | postPayment |
1.2 名副其实
好的命名可以节省未来的时间,让代码更易读,变量名应该清楚地说明变量的用途和功能,如果需要注释来解释,那么这个名字可能不够好。例如下面的命名方式不够明确。
int d;
更好的命名是:
int elapsedTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays;
下面的代码难以理解,因为它缺乏上下文。我们需要知道theList是什么,4代表什么,以及如何处理返回的列表:
int theList[] = { /* ... */ };
int list1[100];
int list1Size = 0;for (int i = 0; i < sizeof(theList) / sizeof(theList[0]); i++) {if (theList[i] == 4) {list1[list1Size++] = theList[i];}
}
通过改进命名和添加上下文,代码可以更清晰,含义为找出所有标记为“已标记”的单元格:
int gameBoard[] = { /* ... */ };
int flaggedCells[100];
int flaggedCellsSize = 0;for (int i = 0; i < sizeof(gameBoard) / sizeof(gameBoard[0]); i++) {if (gameBoard[i] == FLAGGED) {flaggedCells[flaggedCellsSize++] = gameBoard[i];}
}
进一步,使用结构体和函数来隐藏复杂性,代码不仅简洁,而且易于理解。
typedef struct {int status;
} Cell;Cell gameBoard[] = { /* ... */ };
Cell flaggedCells[100];
int flaggedCellsSize = 0;for (int i = 0; i < sizeof(gameBoard) / sizeof(gameBoard[0]); i++) {if (gameBoard[i].status == FLAGGED) {flaggedCells[flaggedCellsSize++] = gameBoard[i];}
}
1.3 避免误导
- 避免使用具有歧义的变量名:不要使用可能会引起混淆的变量名,如hp、ix和sco,这些UNIX平台或类UNIX平台的专有名词。
- 使用描述性的变量名:不要使用像p这样的模糊缩写,即使它看起来是一个方便的缩写,也应该避免,因为它可能会引起误解。
- 使用准确的数据结构命名:例如用accountList来表示一组账号,但变量不是列表(List)类型,不应该在变量名中使用List,使用accountGroup或bunchOfAccounts更加清晰。
- 避免使用相似的变量名:不要使用容易混淆的变量名,如YZControllerForEfficientHandlingOfStrings和XYZControllerForEfficientStorageOfStrings。
- 保持命名一致性:对于相同概念的命名,应该保持一致,以便于代码的自动补全和阅读。
- 避免使用易混淆的字符:不要使用小写字母l和大写字母O,以及数字1和0,因为它们在视觉上容易混淆。
- 每个概念对应一个词:选择一致且直观的命名对维护代码至关重要。例如,对于获取数据的操作,始终使用"get"前缀,而不是混用"fetch"或"retrieve"。
- 不同概念对应不同的词:应避免使用同一术语表示不同的概念。尽管在多个类中使用相同的方法名(如add)可以保持一致性,但如果这些方法在语义上不等价,就应该选择更精确的术语(如insert或append)来命名。
1.4 有意义的区分
- 不同概念对应不同的词:应避免使用同一术语表示不同的概念。尽管在多个类中使用相同的方法名(如add)可以保持一致性,但如果这些方法在语义上不等价,就应该选择更精确的术语(如insert或append)来命名
- 使用有意义的变量名:变量名应该能够清晰地表达其用途和含义,不要仅仅为了满足编译器或解释器的需求而随意更改变量名,这可能会导致代码难以理解。
- 避免使用数字系列命名:使用如a1、a2、aN这样的命名方式是不推荐的,因为它们没有提供任何有用的信息。
- 避免使用废话:不要使用像Info、Data这样的模糊词汇,它们没有提供额外的意义。
- 使用前缀区分变量:在适当的情况下,可以使用前缀来区分变量的作用域或用途,如用g_表示全局变量,h_表示局部变量。
- 避免冗余:不要在变量名中使用如Variable、Table、String等不必要的词汇,因为它们增加了冗余而没有提供额外的信息。
- 明确区分相似的名称:如果有两个相似的变量或函数,它们的名称应该能够清楚地区分它们的作用。
1.5 使用读得出来的名称
- 避免难以理解的缩写:除非是广泛认可的缩写,否则避免使用难以理解的缩写。
- 使用自然语言:变量名应该尽可能接近自然语言,以便更容易理解其含义。
- 避免自造词:不要创造难以理解或发音的词汇。
例如,使用generationTimestamp和modificationTimestamp这样的命名,不仅清晰表达了变量的用途,而且在讨论代码时易于口头交流。
// 定义一个结构体来表示客户信息
typedef struct {time_t generationTimestamp; // 生成时间戳time_t modificationTimestamp; // 修改时间戳char recordId[10]; // 记录ID
} Customer;
1.6 使用可搜索的名称
为了提高代码的可读性和可维护性,应避免使用单字母变量名和不易识别的数字常量。这些命名方式可能会在代码中难以查找和理解。相反,应使用具有描述性的名称,这样即使代码很长,也容易搜索和识别。
// 定义常量
const int WORK_DAYS_PER_WEEK = 5;//定义变量
int realDaysPerIdealDay = 4;
int sum = 0;// 定义任务估计数组
int taskEstimate[] = {10, 20, 15, 25, 30}; // 假设有5个任务
const int NUMBER_OF_TASKS = sizeof(taskEstimate) / sizeof(taskEstimate[0]);for (int j = 0; j < NUMBER_OF_TASKS; j++) {int realTaskDays = taskEstimate[j] * realDaysPerIdealDay;int realTaskWeeks = realTaskDays / WORK_DAYS_PER_WEEK;sum += realTaskWeeks;
}
1.7 避免过度使用编码
在现代编程实践中,过度编码的变量名和成员前缀(如m_表示成员变量)通常被认为是不必要的,变量名应简洁且易于理解。
- 避免过度编码:不要将类型或作用域编入变量名,这会增加理解代码的难度。
- 避免成员前缀:通过编写小类和方法,以及使用现代编辑器的高亮显示功能,可以减少对成员前缀的需求。
下面示例没有使用成员前缀或类型编码,而是直接使用description作为变量名,这样更加直观和易于理解。
// 设置零件的描述
void setPartDescription(Part* part, String description) {part->description = description;
}
1.8 使用专业领域的名称
- 使用解决方案领域名称:例如在能源领域软件开发中,使用“EnergyOptimizer”作为类名,因为它直接反映了代码的功能,即优化能源使用。
- 使用源自所涉问题领域的名称:当技术术语不足以描述功能时,应采用与能源领域相关的名称,如“SolarPanel”或“WindTurbine”。
- 添加有意义的语境:在命名时,应确保变量名在当前上下文中具有明确含义。例如,使用“gridVoltage”、“gridCurrent”比单独使用“voltage”、“current”更能说明这些变量是电网测量值的一部分。如果可能,最好将相关变量封装在“ElectricGrid”类中。
- 不要添加没用的语境:避免在命名中添加不必要的前缀或后缀,例如,简单的“Address”类名比“GSDAccountAddress”更为清晰和恰当,除非有特定的区分需求,否则应避免冗长的命名。