笔者参照《代码精进之路——从码农到工匠》写了这篇关于程序的命名的文章,本文对原文做了一些简化,编程语言从java改成了python,大家如果有时间,可以去看下这本书。
命名的重要性不再赘述,下图是这篇文章的脉络,
主要包括3个大点(命名要有意义,保持一致性和代码要自明),其中又包含了10小点(变量名,函数名,类名;每个概念一个词,使用对仗词,后置限定词,统一业务语言,统一技术语言;使用中间变量,小心注释)。
1.命名要有意义
1.1变量名:
变量名应该是名词,能够正确地描述业务,有表达力。如果一个变量名需要注释来补充说明,那么很可能说明命名就有问题。以下是对“入学时间”的命名
#不恰当的命名:
time=xxx
#恰当的命名:
admission_date=xxx
一些常数也应该用变量名(常量)表示,使代码表达更清晰,且便于搜索与修改。
#每个月有26个工作日,每个工作日工资100元,求每个月的收入
#不恰当的变量名
incom=26*100
#恰当的变量名
work_time_per_month = 26
daily_wage = 100
incom_per_month = work_time_per_month * daily_wage
1.2函数名:
函数的命名要体现做什么,而不是怎么做。以用socket从PLC中读取设备编号为例:
#不恰当的函数名
def read_data_from_socket(self)
#恰当的函数名
def get_mashine_id_from_PLC(self)
1.3类名:
类是面向对象中最重要的概念之一,是一组数据和操作的封装。对于一个应用系统,我们可以将类分为两大类:实体类和辅助类。
- 实体类承载了核心业务数据和核心业务逻辑,其命名要充分体现业务语义,并在团队内达成共识,如Customer、Bank和Employee等。
- 辅助类是辅佐实体类一起完成业务逻辑的,其命名要能够通过后缀来体现功能。例如,用来为Customer做控制路由的控制类CustomerController、提供Customer服务的服务类CustomerService。
《代码精进之路——从码农到工匠》中还谈及了包,库的命名,但此包非彼包,java与python的一些相同术语所对应的意义不一样,而我对此也没有深入的了解,所以会在更加合适的时机来补充这一部分。
2.保持一致性
2.1每个概念一个词
凡是写过代码的往往都会遇到一个问题,即一个中文可以用很多个英文来表示,比如获得一个数据,我们有时会用get,有时用fetch,甚至用拼音。很多时候用get和fetch或其他进行命名都没什么关系,关键是在于保持一致性,不能前面用get,后面用fetch。最好能在项目开始前就约定好。以获得学生相关信息的函数名为例
#不恰当的函数名
def get_student_id()
def fetch_student_score()
def duqu_student_sex()
#恰当的函数名
def get_student_id()
def get_student_score()
def get_student_sex()
还有一个经常在概念上出问题的是“总数与序号”,建议不要使用Num,容易混淆,可以用id代表序号,用count或total代表总数。
2.2使用对仗词,
像first/last之类的对仗词就很容易理解;而像fileOpen()和fClose()这样的组合则不对称,容易使人迷惑,所以要多使用对仗词。
2.3后置限定词
以苹果重量的最大值,最小值和均值为例
#不恰当的变量
max
min
avg
#恰当的变量
apple_weight_max
apple_weight_min
apple_weight_avg
2.4统一业务语言
笔者在上文强调了《代码精进之路——从码农到工匠》是针对java写的,而本文是摘取了这本书的精华,再根据python的相关规范写的。这就是为了统一业务语言,java和python的编码规范不同,如果我们一开始不把这件事给理清楚,我们会容易陷入鸡同鸭讲的地步。
2.5统一技术语言
有些技术语言是通用的,业内人士都能理解,我们应该尽量使用这些术语来进行命名。这些通用技术语言包括DO、DAO、DTO、ServiceI、ServiceImpl、Component和Repository等。
3.自明的代码
所谓自明性,就是在不借助其他辅助手段的情况下,代码本身就能向读者清晰地传达自身的含义。
3.1中间变量
有的朋友喜欢把一行代码写的很长,甚至在抄别人代码的时候,把别人分开多行写的代码写成了一行,其实这并不是一个好习惯,很大程度的降低了代码的可读性。
3.2小心注释
注释要解释意图,不能复述功能,甚至可以写个函数来避免使用注释.为了复述代码功能而存在的注释,主要作用是弥补我们表达意图时遭遇的失败,这时要考虑这样的注释是否是必需的。如果编程语言足够有表达力,或者我们擅长用代码显性化地表达意图,那么也许根本就不需要注释。因此,在写注释时,你应该自省自己是否在表达能力上存在不足,真正的高手是尽量不写注释。
#不恰当的注释,延迟1秒
#恰当的注释,延迟1秒,等待计算结果
sleep(1000)
get_solution()
#使用函数封装,避免注释
def wait_for_solution():
sleep(1000)
wait_for_solution()
get_solution()