代码整洁之道 — 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”更为清晰和恰当,除非有特定的区分需求,否则应避免冗长的命名。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

几度春风里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值