给代码起个好名字

在公司里,我有个不怎么经常使用的绰号,叫“算命先生”——帮别人起名字的,准确说,帮别人的代码起名字,包括项目名,目录名,类名,属性名,方法名,变量名等。事实上,我也确确实实帮过别人起名字,起名字总归有些套路,要避开一些坑,一个好的名字就是一个成功的开始,反之可能后面会带来不少困扰。我跟同事说,好的名字让你行走江湖更容易,你看“叶孤城”、“西门吹雪”、“东方不败”这些名字一听就知道是绝世高手,但你试着叫“王霸天”、“李二狗”、“牛春花”,不是活不过两集就是连上镜的机会都没有。
 
下面分享一些我的的经验及见解,全部的观点都并不是绝对,当你看完整篇文章后确定也深觉得然,我所提出的这些套路也是为了这么个中心服务的: 使得代码更有条理和可读性。

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),我是许多年前在《程序员修炼之道》这本书上看到的(这本书强烈推荐一下),这个道理很简单,就是说若是你一开始对系统中出现的破败视而不见的话,更多的破败就会出现,直到事态不可挽回。你对代码的命名不认真,马马虎虎,致使同事看不懂,同事误会了你的意思,跟着你乱命名,你再次接手这代码的时候,已经凌乱不堪,你感受已经很难维护,因而更加得过且过,直到程序没人再敢去碰。
 
“宇宙的熵在升高,有序度在下降,像平衡鹏那一望无际的黑翅膀,向存在的一切压下来,压下来。但是低熵体不同,低熵体的熵还在下降,有序度还在上升,像漆黑海面上升起的磷火,这就是意义,最高层的意义,比乐趣的意义层次要高。”——《三体:死神永生》
相关文章
相关标签/搜索