给代码起个好名字
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
给代码起个好名字
在公司⾥,我有个不怎么常⽤的绰号,叫“算命先⽣”——帮别⼈起名字的,准确说,帮别⼈的代码起名字,包括项⽬名,⽬录名,类名,属性名,⽅法名,变量名等。
事实上,我也确确实实帮过别⼈起名字,起名字总归有些套路,要避开⼀些坑,⼀个好的名字就是⼀个成功的开始,反之可能后⾯会带来很多困扰。
我跟同事说,好的名字让你⾏⾛江湖更容易,你看“叶孤城”、“西门吹雪”、“东⽅不败”这些名字⼀听就知道是绝世⾼⼿,但你试着叫“王霸天”、“李⼆狗”、“⽜春花”,不是活不过两集就是连上镜的机会都没有。
下⾯分享⼀些个⼈的经验及看法,所有的观点都并⾮绝对,当你看完整篇⽂章后肯定也深以为然,我所提出的这些套路也是为了这么个中⼼服务的:使得代码更有条理和可读性。
1,⽤英⽂,别⽤中⽂,别⽤拼⾳,更加别⽤拼⾳缩写
这应该是⽼⽣常谈了。
C#/Java语⾔挺神奇,可以⽤中⽂做标识符,⽐如你创建⼀个类,叫“货物订单”,完全没问题,但有⼈尝试过之后就很快放弃了,因为可读性实在太差了,另外在做代码搜索的时候,输⼊中⽂本⾝就⽐英⽂要慢,英⽂还⽅便⽤正则等去匹配,中⽂在这⽅⾯操作起来就⽐较困难,如果你还想把代码移植到别的语⾔去,就更加不能⽤中⽂了。
拼⾳也别⽤,因为拼⾳你不念出来的话你往往不知道它想表达什么意思,汉语拼⾳中还有声调,⽽代码中⼜表⽰不了,有时候真能让阅读者⼀脸懵逼。
那拼⾳缩写就更加不⽤说了,我维护过⼀些⽼古董代码就全是拼⾳缩写,恶⼼+崩溃。
好不好不好垃圾
GoodsOrder商品订单ShangPinDingDan Spdd
InventoryCheck库存盘点KuCunPanDian kcpd
InvoiceManagement发运单管理FaYunDanGuanLi fydgl
RouteConfiguration路由配置LuYouPeiZhi lypz
2,不要拼写错误
这不是废话么?但也不知道是由于不⼩⼼还是英⽂⽔平太差,我遇到的代码中的拼写错误实在太多太多了,更有甚者把公司的名称都写错的。
如果你哪天⽤微软的代码,发现命名空间是:Micorsoft.Extensions.Logging,你会有什么感受?
写代码和做别的事情⼀样,也需要⽤⼼,遇到不确定的东西时,查⼀下,问⼀下,如发现⾃⼰之前的问题,要及时修正。
随便列举⼀些拼写错误(跟技术⽆关,纯粹看英语⽔平和仔细程度)
错误正确描述
lable label字母前后写错是常发⽣的事情
catched caught catch的过去分词为不规则
loging logging注意添加-ing的特例
IsEnable IsEnabled Enabled才是形容词,才能⽤系动词
登陆登录你以为中⽂的错别字就少了?
SingleBox PackingList本公司的梗,“发票箱单”,某同事翻译成了Single(单)Box(箱),奇葩
3,⽤名词充当类名
类,通常表⽰⼀个数据实体,或者⼀系列数据与⽅法的封装,⼤多时候是应当使⽤名词的。
下⾯是⼀些例⼦:
名称不太好不错
登录信息Login(这是动词唉)LoginReq(Req表⽰Request,⼀看就知道这是个登录请求)或LoginUi,后缀Ui表⽰UI层使⽤的类。
出库订单Order(太普遍了,且order是SQL的关键字,容易带来⼀些不便)OutBoundOrder
全局变量Global(这是形容词)GlobalData,GlobalAppConfig等
总线请求类BusRequest(这是动词)BusRequester(请求者,凑合,但仍不太好) BusReqManager(这个名字明显更好)
4,不要使⽤太普遍的名词充当类名
如Configuration,这个词表⽰配置,你打算创建这么⼀个类表⽰系统的配置信息,并提供相应⽅法。
但你要注意了,⼀个较⼤的系统⾥通常有很多很多的配置,⽐如程序的全局配置,⼊库规则配置,出库规则配置,外部接⼝访问配置,⽇志配置……如果你全都叫Configuration,你很可能三天两头被⾃⼰搞懵。
那怎么办?写具体点不就⾏了么?
不好好⼀点说明
Configuration GlobalApplicationConfiguration InBoundConfiguration ExteralApiConfiguration LoggingConfiguration
起码更具体了
Param
(某个外部API 的参数)GenericExternalApiParam标识符命名没必要再从技术上描述它是什么东西,正如你不需要写完“int i=1”后加个注释“定
义整型变量i并赋值1”,要使得名字符合业务逻辑
当然,也有例外的情况,⽐如我的项⽬中通常有个类叫“Fmt”,⾮常简单,其实就是Format的简写,这个类不涉及到具体的业务逻辑,只是⽤来对时间⽇期和数值进⾏⼀些格式化操作,所以可以起个这么简的名字。
5,适当的简写与约定俗成的缩写
上⾯起的名字你是不是觉得太长了?那可不可以缩写⼀些?那是肯定的,代码中,我们存在着很多约定俗成的“单词”,举个最简单的例⼦:ID,ID是Identity的简写,为什么我们现在都知道?因为已经“约定俗成”了,这种例⼦还很多,我随便举⼀些:
原本简写
participant ptcp
application app
description desc
abbreviation abbr
configuration config或cfg
Machintosh Mac
缩写的规则通常是取前⾯⼏个字母,但也有例外的,如前⾯提到的participant,如果缩写为part的话,由于part是另外⼀个单词,容易引起误会,所以就取participant中的⼏个与发⾳相关的辅⾳字母来组成简写,所以configuration也可以简写为cfg,关键是要⼤家都认可。
6,约定俗成的缩写
英⽂中的缩写实在太多了,如果没有这些缩写,⽤英语就简直⽆法交流,我并不夸张,随便写⼏个缩写的例⼦:
英⽂缩写英⽂全称中⽂
NASA National Aeronautics and Space Administration美国国家航空和宇宙航⾏局
BASIC Beginner's All-purpose Symbolic Instruction Code初学者通⽤符号指令代码
EPROM Electrically Programmable Read-Only-Memory电可编程序只读存储器
JSON JavaScript Object Notation JavaScript对象表达式
ASN Advanced Shipment Notice预到货通知单
DN Delivery Number运单号
现在你有问题了:“你前⾯刚说拼⾳缩写‘垃圾’,为什么这⾥⼜允许英⽂缩写?”Good question,我这样说吧:关键点在于约定俗成,⼤家认可,英⽂中的缩写词经常能⾃⼰成为⼀个单词,如ROM,我们都直接念它“[rɔm]”,⽽不是“R-O-M”,⼤家都已经认可了“ROM”这个单词了,这就可以了。
⽂章⼀开始我也说了,所有这些,都是为了这个中⼼服务的:使得代码更有条理和可读性!所以我提出的建议也只是建议,不是铁律。
这么说的话,我们是不是拼⾳缩写在某些时候也能⽤⼀下?——没错,我们公司经常就⽤Shwgq来表⽰“上海外⾼桥”,⼀来“上海外⾼桥”是专有名词,只能写拼⾳,⼆来公司同事都已经认可了,于是就可以愉快地使⽤了,但我⼜要说回来,这个是个特例,千万不要滥⽤。
7,驼峰命名法
先问这么⼀个问题:UserID好,还是UserId好?
也许你有你的看法,⽽我的看法很明确:UserId好,因为它很好地区分出了ID这个“单词”,前⾯说了ID是Identity的简写,但认可的⼈多了之后,ID本⾝就成为了⼀个单词,根据驼峰命名法的规则,单词⾸字母⼤写,其余⼩写,因此应当写UserId,可能⼀开始感觉有点不习惯,但后⾯很快就能适应。
另外还有⼀个问题:UserName好,还是Username好?
按规则应该是Username,因为这本⾝就是⼀个单词,但由于历史原因,在我的项⽬⾥⾯,⼀律写成UserName,以前写错了,惯性太⼤,改不了,就当是User和Name两个单词拼成的吧——看吧,兵⽆常势⽔⽆常形,要灵活应变。
另外还要注意⼀点,⽤驼峰命名法的时候,避免连续出现⼤写字母,否则很影响代码可读性。
8,适当使⽤后缀区分
有时候实在不知道怎么起名字,如登录,叫“Login”,这个也许表⽰客户端向服务器提交的登录请求,但也能表⽰服务器处理好登录请求后返回给客户端的信息,怎么办?
我的办法是加上后缀作区分:
登录登录请求登录响应
Login LoginReq LoginResp
这样就⾮常清晰了,Req即Request,Resp即Response,这种⽅法还能把Login这个动词变作⼀个名词,太好⽤了。
再⽐如,员⼯信息,叫EmployeeInfo,它可以是来⾃客户端的提交的信息,根据系统的分成架构,这个Model需要从UI层传递到业务逻辑层,但这两个层的EmployeeInfo类是有差别的,难道都要叫EmployeeInfo,只⽤命名空间来区分吗?我的“套路”⼀般如下:
员⼯信息UI层的员⼯信息业务逻辑层的员⼯信息
EmployeeInfo EmployeeInfoUi EmployeeInfoBl 或 EmployeeInfo
UI层加上Ui后缀(根据前⾯提到的规则,i⼩写),业务逻辑层可以加上Bl,也可以不加,因为UI层加了,就表⽰可以区分开来了。
9,⽤谓宾结构来命名⽅法
⽅法表⽰某个执⾏动作,通常都是谓宾结构,为什么把主语省掉了?因为主语100%是调⽤者,根本不⽤问。
这是⼀些例⼦:
⽅法好
报关单作废CancelDeclaration
检验是否存在CheckIfExisting
出库确认ConfirmOrder
删除核放单DeleteGatebill
没太多好说的,在动词的选择⽅⾯,有以下这些常⽤动词:
动词英⽂
创建Create
增加Add(注意跟“创建”语义上的差异)
更新/编辑Update/Edit
删除/移除Delete/Remove
清空Clear/RemoveAll
获取/设置Get/Set
发送/接受Send/Receive
检查是否XXX CheckIf
⽣成Generate
计算Calculate
上传/下载Upload/Download
万能动词Do/Make
还有很多,我不列了,否则就真的变成上英语课了,英语和汉语⼀样,同义词很多,但语义上常常会有些微⼩的差异,⽐如创建和增加,创建⼀个新⽤户,这是⼀个从⽆到有的过程,所以通常⽤Create,⽽将这个创建好的⽤户加到开发部门中去,则是Add的概念,开发部门本来就存在的,只是多了⼀个⼈,⼤家去体会体会。
我们在选动词的时候通常会选⽐较符合英⽂⽂法的词,⽽不能太过于“技术”,如选择Create ⽽不是SQL的Insert,因为Insert是个数据库技术中的概念,⽽不是业务逻辑上的概念,再如选择Send⽽不是Post,也是⼀样道理,但这个并不绝对,假如你开发的是⼀个⽹络访问的基础库,那么你完全可以⽤Post啊,因为这个情形下,Post本⾝就更能描述业务逻辑。
实在不知道怎么选动词的话可以考虑下Do和Make这两个万能动词,DoXxx,可以表⽰⼲任何事情,⽽Make⼀样很万能,Trump⼤帝竞选美国总统的时候⼝号不是“Make American Great Again”么?使或让的意思,放在很多场合都适⽤,再⽐如Make money,“赚钱”的意思。
10,复数与列表
有次我复查代码,看到⼀个“订单”中的“订单明细”是这么命名的:OrderLineCounts。
莫名其妙,这根本不通啊。
⽤“Line”表⽰明细是我们公司的约定俗成,⼀个订单主档中带若⼲订单明细,我说⽤来表⽰这种明细列表通常有两种⽅法,⼀种是⽤复数,另⼀种加个List后缀:
不通通通
OrderLineCounts OrderLines OrderLineList
这⾥还要注意⼀下:
1,不是所有名词都有复数形式,英语中有些词不可数对不?所以加个List后缀可能更通⽤⼀些
2,不是所有可数名词都可以直接加s变成复数形式,如Data,其复数形式应该是Datum,不要写Datas
3,有些单词单复数同形,如Goods,商品,复数也是Goods,不要写作Goodses
最后
讲⼀个东西,叫“破窗效应”(Broken Window Theory),我是许多年前在《程序员修炼之道》这本书上看到的(这本书强烈推荐⼀下),这个道理很简单,就是说如果你⼀开始对系统中出现的破败视⽽不见的话,更多的破败就会出现,直到事态不可挽回。
你对代码的命名不认真,马马虎虎,导致同事看不懂,同事误会了你的意思,跟着你乱命名,你再次接⼿这代码的时候,已经凌乱不堪,你感觉已经很难维护,于是更加得过且过,直到程序没⼈再敢去碰。
“宇宙的熵在升⾼,有序度在降低,像平衡鹏那⽆边⽆际的⿊翅膀,向存在的⼀切压下来,压下来。
可是低熵体不⼀样,低熵体的熵还在降低,有序度还在上升,像漆⿊海⾯上升起的磷⽕,这就是意义,最⾼层的意义,⽐乐趣的意义层次要⾼。
”——《三体:死神永⽣》。