【整理】编码命名规范建议
Jun 12, 2022笔记编码规范编码命名规范建议
编程中命名习惯的改进
当我们看到一段代码时,最先注意到的,不是代码有几层循环,用了什么模式,而是变量与注释,因为它们是代码里最接近自然语言的东西。
写代码前先决定名字。
命名的指导方针
- 名字中要尽量多包含信息。
- 名字不能有歧义。
- 名字说明的是效果和目的,而不是手段。
- 可以通过先写测试程序后写处理的方式检查一下自己取的名字是否合适。
- 名字要能念出来。
- 名字要能搜索出来。
有一种叫做“名字可逆性”的命名思路,主张名字必须能还原其所指内容的说明文本。要想满足这一条件,就需要进行环回检测。先通过内容的说明文本来想名字,再通过名字倒推出说明文本。按照说明文本、名字、说明文本的顺序绕一圈回来后,如果说明文本一致,那这个名字就是好名字,如果不一致就需要我们注意了。
*心理映射:读代码的人看到某元素名字后需要先在心里把它转换成自己知道的东西,这个过程就是心理映射,我们应该极力避免这种情况发生。
命名的基本原则
- 全部采用易懂的英文来命名,可以辅以下划线和数字;
- 名称长度尽量不要超过16 个字符(有些常量名称可能长度会比较长);
- 不要采用无意义的名字;
- 每个单词之间应该有合适的分割,可以采用大小写间隔,也可以采用下划线;
- 除了常量以外,都应该是大小写混合的形式,即使是 FTP,也要写成 Ftp;
- 遵循编程语言的标准,比如 Python 遵循 PEP8 编码风格。
格式
1.snake-case
蛇形命名法, 规定复合词或短语中的各个单词之间用下划线(_
)分隔并且没有空格。复合词中的每一个单词的首字母通常都是小写的,并且复合词的第一个字母既可以是大写的又可以是小写的。
1 | 例如: lisp_case、kebab_case、SCREAMING_SNAKE_CASE |
2.camel-case
驼峰命名法,其中又可分:
lower-case:小驼峰命名法,第一个单词的首字母小写;第二个单词开始每个单词的的首字母大写。常用于方法名、参数名、成员变量、局部变量。
1 | 例如: firstName、lastName |
upper-case / pascal-case:大驼峰命名法,每一个单词的首字母都大写。常用于接口或类名。
1 | 例如: FirstName、LastName、CamelCase |
3.kebab-case
短横线命名法。
1 | 例如: v-bind |
变量和常量
通用规则
- 尽量不要使用拼音,杜绝拼音和英文混用。对于一些通用的表示或者难以用英文描述的可以采用拼音,一旦采用拼音就坚决不能和英文混用。正例:BeiJing, HangZhou 反例:validateCanShu
- 命名过程中尽量不要出现特殊的字符,常量除外;
- 尽量不要和全局变量或者框架中已存在的类重名,也不能使用编程语言中的关键字命名;
- 妙用介词,如 for(可以用同音的 4 代替), to(可用同音的 2 代替), from, with,of 等。如类名采用 User4RedisDO,方法名 getUserInfoFromRedis,convertJson2Map 等;
- 避免误导。要注意使用小写字母 i 和大写字母 O 作为变量名,看起来像“壹”和“零”;
- 使用可搜索的名称。单字母名称和数字常量有个问题,就是很难在一大篇文字中找出来;
- 言到意到,意到言到,别扮”可爱“,别用双关语。
变量命名
变量是指在程序运行中可以改变其值的量,包括成员变量和局部变量。
为变量命名要结合代码情境和上下文,变量命名时,尽量简短且能清楚的表达变量的作用,命名体现具体的业务含义即可。
通用格式:
- 变量名由多单词组成时,第一个单词的首字母小写,其后单词的首字母大写,俗称骆驼式命名法(也称驼峰命名法,lower-case),如 computedValues,index。
- 变量名不应以下划线或美元符号开头,尽管这在语法上是允许的。变量名应简短且富于描述。变量名的选用应该易于记忆,即,能够指出其用途。尽量避免单个字符的变量名,除非是一次性的临时变量。pojo(简单的 Java 对象,实际就是普通 JavaBeans)中的布尔变量,都不要加 is(数据库中的布尔字段全都要加 is_ 前缀)。
- 变量名描述性要强,但不宜过长,尽量不要超过 4 个单词。
- 在同一段代码内,不要出现多个相似的变量名。
其他:
- 变量越多,就越难全部跟踪它们的动向;
- 变量的作用域越大,就需要跟踪它的动向越久;
- 变量改变得越频繁,就越难以跟踪它的当前值。
常量命名
通用格式:
- 常量要采用全部大写的形式进行命名,如果有多个单词,用下划线进行分割;
- 常量的命名不要采用序号式命名;
- 常量应该通过其开头词进行分组。
其他:
- 常量一般都有自己的业务含义,不要害怕长度过长而进行省略或者缩写。如,用户消息缓存过期时间的表示,那种方式更佳清晰,交给你来评判。
- 虽然很多常量名字本身已经很清楚感觉不需要注释,但是可以通过加注释得以改进,比如定义这个常量时的想法。
相似的命名
- *Form(获取页面输入)、持久化(想数据库存取数据)、View(想页面显示数据)的重复:难免会产生这三层需要采用同一个名称的情况,最佳方法就是将三者合一,通过 Annotation 来完成各自不同用途的格式定义,从而减少命名重复的困扰。
- 层 1、层 2……层 n 的无形层的重复:可以采用
~Form
、~Wapper
、~Layer
分别对不同的包装容器进行命名来规避这个问题。 - 类和内容的重复:一般来说,容器和内容之间都会有不同的名词,例如房子和家具、菜篮子和蔬菜、问卷和问题。
- 整体和部分:可以通过增加前缀来区分部分和整体,例如 matched、filtered、grouped、wrapper。
- 类型转换:可以通过连续调用来略过类型转换时的中间变量。
从问题出发
1.从阅读者角度,一些常见的编码问题
- 一直滚动鼠标滚轮——方法过长;
- 总是全局搜索——方法过长;
- 反复地查看方法实现——命名无法反映其真实含义;
- 不停地查看调用方法实现——调用层数太多;
- 反复查看全局常量的值——常量定义方式无法反映其实质;
- 画流程图——嵌套太深。
在阅读上的问题分为以下 5 类:
- 命名类问题
- 注释类问题
- 结构类问题
- 架构类问题
- 风格类问题
其中与命名相关的问题:
命名类问题
代码能够用尽可能短的命名来表征尽可能多的含义。
- 缺乏统一性:类/接口/方法/变量命名都应该遵守一定的规则;
- 没有考虑调用时的情形;
- 本地语言命名:除非专有名词,否则还是要用英语;
- 命名用词不当:所使用的英文有误、可能引起误解。如:
- research 不能表示重新检索,想要表示重新检索应该用 searchAgain;
- limit 表示极限而不是限制,restriction 或者 constraint 才表示限制;
- fasten 表示固定而不是加速,accelerate 才表示加速。
- 超长的命名:超长的命名回花费较多时间阅读,也不容易记忆。例如 internationalization 这个词汇已经被缩略为 i18n,以方便书写和记忆。
- 是否需要使用缩略词,取决于团队的新成员是否能理解这个名字的含义。
- 命名含义模糊
- 命名和行为不一致:承诺多做得少;承诺少做得多;言行不一。
- 否定式命名:否定式命名往往会引起阅读成本。
- 无意义命名:temp、result、retVal 这些不表征具体的含义,包含的信息量少。
- 序号式命名:序号并不能表明其真实含义,例如 layer0、layer1.
- 工程名为类名前缀:把工程名作为类和接口的前缀是一种画蛇添足的行为,会降低阅读的速度。
- 超短命名:a、b、c 这种也无法获取有用信息,但注意循环体中约定俗成的 i、j、k 是无妨的。
- 匈牙利命名法:匈牙利命名法可以帮助读者了解数据的类型方面,但在例如面向对象的编程风格中代,编写的代码难以形成统一易懂的缩写。应当把类和函数做得足够小,消除对成员前缀的需要。
注释类问题
当代码通过其名称和符号无法很直观地表达其含义时,需要注释来帮助说明代码的作用。
- 复制名称的注释:这种注释无法起到帮助作用。
风格类问题
- 冗余的常量定义:
- 有些可在原输入基础上补充而无需采用长常量列表的场景。不要使用一个常量类维护所有常量,按常量功能进行归类,分开维护。大而全的常量类,非得使用查找功能才能定位到修改的常量,不利于理解和维护。合适的做法比如缓存相关常量放在类 CacheConsts 下;系统配置相关常量放在类 ConfigConsts 下。
- 常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量。
1) 跨应用共享常量:放置在二方库中,通常是 client.jar 中的 constant 目录下。
2) 应用内共享常量:放置在一方库中,通常是子模块中的 constant 目录下。
- 变量意思不稳定:有歧义。
- 返回值意思不稳定
- 无用的方法或变量:特别是类中无用的 public 方法难以被发现。
问题产生的部分原因
编程习惯不佳
- 命名习惯不好:
is
等作用域开头等,变量名称和方法名称容易无法区分。 - 没有管理好代码的责任:UI 和数据和逻辑。
- 不考虑调用时的样子:调用时可能难以理解,要认真设计调用、比如接口。
- 不考虑命名的一致性:比如
remove
/delete
。 - 方法命名必须以动词开头:方法命名必须为动词,或者动词+名词的形式,因为方法必须是动作。但不绝对,比如
List.size()
、find.all()
,这样更易读。
英语能力不足
词性不对:对于集合性质的变量命名可以考虑采用其复数形式(有时也会降低阅读成本,这时可以换为在末尾加
List
、Map
),例如可以用books
而不是bookList
。对于将动作变为变量的情况,应该将动作从动词改为动名词。例如可以用action
而不是act
。对于只有开关两种状态的属性来说,可以采用形容词。而对于多种取值的属性来说,则应该采用对应的名词。词汇不对:应该用更为准确的词汇,例如表示缩短,
makeShorter
不如shorten
更贴切;表示认证,doLogin
不如authenticate
更准确。对于一些计算机专业术语也是有一定规定的,例如对于栈Stack
,它的行为应该是Push
和Pop
,而不是Pull
。对于一些行业,也有其特定的术语,例如余额应该是Balance
而不是LeftMoney
。如果不能用程序员熟悉的术语来给手头的工作命名,就采用从所涉问题领域而来的名称。比如有这么个函数为
getPage(url)
,我们虽然可以知道是获取一个页面,但是如果用fetchPage
或者downloadPage
进行更具体的动作区分命名会更好。再比如有个函数为
getSize()
,更为形象化的话可以命名为getHeight()
、getNodeNum()
、getArrLength()
再比如有个函数为
stopAnimation()
,我们不知道它将是终止动画还是中止动画,我们可以命名为killAnimation()
、pauseAnimation()
。下面是一些例子,这些单词可以使命名更有表现力且适合语境
单词 | 更多选择 |
---|---|
send | deliver、dispatch、announce、distribute、route |
find | search、extract、locate、recover |
start | launch、create、begin、open |
make | create、set up、build、generate、compose、add、new |
时态不对:采用动词原型命名的状态值往往会让读者猜测:到底是已经发生了这件事情,还是正在进行这件事情呢?例如
register
、attend
、test
、pass
、failed
,而如果能够结合时态命名则状态的含义就更容易理解了,例如:registered
、atteneded
、tested
、evaluated
。语法没有加善利用:由于受到一些限制和束缚,没有把介词和连词在方法的命名中,代码读起来就不够顺畅,如果把这些词汇放在代码中,代码就会变得更加易读了。例如判断
cell
是否在最后一排:cell.isAtLastColumn()
/gird.isAtLastColumn(cell)
。
英文
词性
- 名词:表示属性的常用词性。
- 动词:一般用来表示方法(处理),方法的名称中一般都应该包含一个动词,其构成形式上一个动词或者动词+名词形式的词组
- 动名词:动作可以作为属性出现,但是应该以动名词的形式表现。例如
action
、configuration
。动作行为也可以作为类或者接口出现,但是最好以动名词或者名词的形式出现,例如class Activity
,class Service
。 - 形容词:形容词作为属性表示某种状态,例如
visible
;用来表示某个状态的属性如果是形容词,一般是布尔型的,而其对应的判定方法则是is
,如isVisible
,其setter
的形式是setVisible
。形容词也可以有多种取值范围,例如可见性除了显示、隐藏之外还增加了正在消失。对于这种情况,需要改用名词来使其多种取值范围得以体现,例如visibility
。 - 代词:代词可以用来指代其他事物,所以具有不必关心被指代事物的类型的特点。
this
(关键词,不能够使用)、what
(当类中需要包含一个可能和自己重名的对象时)、other
(当需要做对比时)、还有that
、when
、where
、who
、which
、me
、you
、him
、self
。 - 介词、连词等:介词、连词等让代码读起来更顺畅。
by
(表示根据后面的条件执行前面的动作,如getLicenseById
)、for
(表示执行前面的动作是为了后面的目的,如waitForIdle
)、at
(表示根据后面的条件执行前面的动作,如removeAt
)、and
(表示两个条件都需要成立才能够执行前面的动作,如saveAndExit
)、or
(表示两个条件只需要其中一个条件成立即可执行前面的动作,如isNullOrEmpty
)、另外还有with
、after
、before
、through
、as
也都可以使用。另外介词、连词也可以作为方法的开头。
时态
动词的时态有很多种,但编程中只要使用其中 3 种即可:
- 一般现在时:表示状态类动作;
- 完成时:表示动作已经完成;
- 进行时:表示动作正在进行。
语法
- 宾语从句,如
assertThat(num).isEqualTo(6)
,读起来更像一句话而不需要更多思考; - 过去时:如
viewDidLoad
表示视图加载完成; - 一般将来时:如
sendDelayed(3)
->updateUiAfter(3)
否定词
- Exception 与 Error 等的命名:异常或者错误本身就表示系统发生错误了,所以异常和错误都可以采用否定式命名以明确表示它原来的意思。如:
- InconvertibleException 表示不能转换;
- FileNotExistException 表示文件不存在。
- 错误常量:当处理发生错误时,有时需要使用错误值进行处理。错误号需要定义为常量,常量的命名可以采用否定式命名,如
INVAILD_CODE
- 特殊类:如输入键盘。
成对词
固定方式出现的成对词能直接想到另一个方法的名称。常用成对词:
get
获取/set
设置max
最大/min
最小start
启动/stop
停止begin
开始/end
结束backup
备份/restore
恢复bind
绑定/separate
分离copy
复制/paste
粘贴clean
清理/clear
清除source
来源/destination
目的地from
来/to
去previous
上一个/current
当前/next
下一个create
创建/destroy
移除plus
加/minus
减positive
积极的/negative
消极的connect
连接/disconnect
断开(或close
)download
下载/upload
上传add
增加/remove
删除add
数字加/sub
数字减add
加入/append
添加increase
增加/decrease
减少enable
启动/disable
废弃encode
编码/decode
解码encrypt
加密/decrypt
解密compress
压缩/decompress
解压缩parse
解析/emit
生成pause
暂停/resume
恢复open
打开/close
关闭initialize
初始/finalize
最后request
请求/respond
响应success
成功/failed
失败top
顶部/bottom
底部include
包含/exclude
排除input
输入/output
输出import
导入/export
导出width
宽度/height
高度read
读取/write
写入load
载入/save
保存split
分割 /merge
合并inject
注入 /extract
提取attach
附着/detach
脱离view
查看/browse
浏览edit
编辑/modify
修改select
选取/mark
标记undo
撤销/redo
重做insert
插入/delete
移除index
索引/sort
排序play
播放/pause
暂停launch
启动/run
运行compile
编译/execute
执行build
构建/publish
发布pack
打包/unpack
解包send
发送/receive
接收refresh
刷新/synchronize
同步update
更新/revert
复原lock
锁定/unlock
解锁check out
签出/check in
签入push
推/pull
拉expand
展开/collapse
折叠begin
起始/end
结束start
开始/finish
完成enter
进入/exit
退出
近义词
近义词如果使用不对,会造成理解上的偏差,如:
invalidate
使无效 /refresh
刷新 /update
更新draw
绘制 /render
渲染 /display
展示/show
显示perform
执行 /process
处理 /do
做 /run
运行 /execute
实施 /invoke
调用picture
图片 /image
图像 /bitmap
位图 /icon
图标 /thumbnail
缩略图size
尺寸 /length
长度refuse
拒绝 /decline
拒绝、下降 /reject
拒绝、否决revoke
撤销 /cancel
取消obsolete
废弃 /depreciate
废旧collect
收集 /aggregate
聚集abort
放弃 /quit
离开submit
提交 /commit
交付find
查找 /search
搜索observe
观察 /listen
监听debug
调试 /trace
跟踪
一个系统中最好不要出现各种同义词。
前缀、扩展名
prev/curr/next
表示顺序on~
表示响应某个行为is~
(表示“是”)/has~
(表示“有”)/need~
(表示“需要”)/can~
(表示“可以”)/allow~
(表示“允许”)表示判定:注意这些词不应该用在域变量上,只能用在方法上。do~
(表示执行某个操作)/process~
/run~
/execute~
/invoke~
/perform~
都表示执行~Wrapper
表示包装器:往往被包装的对象是成组的- 设计模式名字作为结尾:
~State
表示状态模式、~Proxy
表示代理模式 ~Listener
表示事件接收器get~
、set~
表示获取和设置值:注意 boolean 类型的 getter 是用is~
开头的to~
表示转换
缩写
可以帮助缩短命名长度、但是滥用缩写会导致意思不明确。
average
->avg
administrator
->admin
argument
->arg
application
->app
asynchronous
->async
(注意关键字)address
->add
bitmap
->bmp
button
->btn
calculate
->calc
column
->col
connection
->conn
configuration
->conf
command
->cmd
control
->ctl
copy
->cpy
decrease
->dec
delete
->del
default
->def
dictionary
->dict
document
->doc
environment
->env
event
->evt
error
->err
execute
->exec
horizontal
->horz
information
->info
message
->msg
memory
->mem
manager
->mgr
maximum
->max
minimum
->min
table
->tbl
version
->ver
object
->obj
picture
->pic
position
->pos
reference
->ref
subtract
->sub
synchronization
->sync
temporary
->temp
variable
->var
(注意关键字)vertical
->vert
initialize
->init
temporary
->temp
/tmp
length
->len
panel
->pnl
frame
->frm
缩写如果全部都是大写字母,那么作为变量时也应该写为大小写混合。除了 DO
/ BO
/ DTO
/ VO
/ AO
/ PO
,如 UserDO
。
正确用词
- 拼写正确
- 正确用词:如
hasPermission
比isAllowed
更易读,如- 花费的时间不是
usedTime
,而是elapsedTime
- 缩短不是
makeShorter
,而是shorten
- 加快不是
fasten
,而是accelerate
- 限制不是
limit
,而是constraint
或restriction
- 成熟不是
aged
而是sophisticated
- 上下不是
upDown
而是vertical
- 错误级别不是
faultLevel
而是severity
- 花费的时间不是
- 准确的用词:
yyyyMMddhhmmss
->timestamp
- 明确的用词:如
fire
可以表示点燃也可以表示开除 - 精确的用词:子啊列表当中会涉及各种顶点、节点、缝隙、元素之间的关系,需要有一套整体的命名规则,来为各个元素定义清楚其用词。
*注释方面的改进
注释作为代码之外的说明性文字,应该尽量提供那些读者无法从代码里读出来的信息,描述代码为什么要这么做,而不是简单复述代码本身。若编程语言足够有表达力,就不需要注释。注释的恰当用法是弥补我们在用代码表达意图时遭遇的失败。
注释总是一种失败,不准确的注释要比没注释坏得多。
除了描述“为什么”的解释性注释外,还有一种注释:指引性注释,这种注释不直接复述代码,而是简明扼要地概括代码功能,起到“代码导读”的作用。
注释 jsdoc/javadoc 标签:
@see
:表示参照代码,子类或实现类通过次连到声明类@link
:表示连接,通过这个连接可以连到另外一个类的说明中去@code
:表示应用一个值@param
:表示参数@return
:表示返回值@throw
:表示方法抛出的异常@author
:表示作者@version
:表示版本@since
:表示自哪个版本开始使用该方法@example
:表示演示使用方式
TODO、FIXME 和 XXX
FIXME
:表示这段代码没有正确处理,需要修改TODO
:表示这段代码尚未完成,需要实现XXX
:表示这段代码目前可以完成工作,但是还需要改进。HACK
:表示对一个问题不得不采用的比较粗糙的解决方案
类的注释
- 类的功能说明
- 类的主要方法介绍
- 类的方法常用调用方式
其他
建议行尾不要加入注释,因为不利于行长的控制。
版权说明
换行
- Annotation 之后要换行;
- 每行处理(分号)之后要换行;
- 每个花括号开头后面要换行;
- 每个花括号结尾后面要换行;
- 每行处理之后要换行;
- 不在同一行上声明超过两个变量;
- 每个变量、常量定义要换行。
无效代码
- 对于不再需要的代码,我们应该直接把它们删掉,而不是注释。
空行
- 适当地在代码中插入空行,把代码按不同的逻辑块分隔开,这样能有效提升代码的可读性。
测试代码的自表达改进
自动测试的结构采用的都是三步结构:
given
: 前提的数据when
: 进行的操作then
: 期望的结果fixture
: 测试夹具前提的数据behavior
: 行为进行的操作expectation
: 期望值期望的结果
前端命名
html 文件的命名
格式:统一用小写的英文字母,单词间用连字符 “-
” 连接,kebab-case (短横线分隔命名)
原则:
- 可移植性。Linux 系统是大小写敏感的,而 Windows 系统和 Mac 系统正好相反,大小写不敏感。
- 易读性。小写文件名通常比大写文件名更易读。
- 易用性:某些系统会生成一些预置的用户目录,采用首字母大写的目录名,用户的文件都采用小写文件名,就很方便与上面这些目录或文件相区分。
- 便捷性:文件名全部小写,还有利于命令行操作。比如,某些命令可以不使用
-i
参数了。
常用命名:
- 首页/主页面:
index.html
- 子页面:
- 首页:
home.html
- 我的:
mine.html
- 关于我们:
about.html
- 信息反馈:
feedback.html
- 产品:
produot.html
- 购物:
shop.html
- 计数器:
count.html
- 购买:
buy.html
- 首页:
- 一级页面:
- 登录:
login.html
- 注册:
resign.html
- 登录:
Image 图片的命名规则
- *可以考虑带上前缀:
i-
表示 logo 类图标、p-
表示普通图片 图片的后缀:
xxx.png
、xxx.jpg
、xxx.gif
、xxx.bmp
、xxx.webp
图片的名称分为头尾两部分,用下划线隔开,头部分表示此图片的大类性质。例如:产品
product
产品下的 -> 电视 / 手机:product_tv product_phone
例如:广告、标志、菜单、按钮等等。
- 放置在页面顶部的广告:
banner
- 企业商标/标志性的图:
logo
- 在页面上某个文字连续出现,性质相同的链接栏目图片:
menu
- 装饰用的照片:
pic
- 标题的图片:
title
文件夹命名/存放规则
frontend
、www
或者web
存放前端代码文件bulid
存放构建等脚本文件css
存放 xxx.css 文件src
存放源码文件views
或者pages
存放 xxx.html 或者 xxx.vuecomponents
存放组件文件assets
存放所有资源文件images
/imgs
存放图片文件library
/lib
存放第三方库文件media
存放媒体文件backend
、serve
存放服务端代码文件api
存放[接口文件]modules
存放[数据库操作]文件
css 书写规范
可见 MooCSS 命名规则:http://blog.michealwayne.cn/Moo-CSS/docs/nameRule/
- 禁止 class 和 id 重名;
- 书写顺序, 建议遵循
布局定位属性-->自身属性-->文本属性-->其他属性
- 布局定位属性 :Margin\padding\float\clear\position ( 相 应 的 top,right,bottom,left)\display\visibility\overflow 等
- 自身属性 :Width\height\background\ border
- 文本属性 :font\color\text-align\text-decoration\text-indent\ white-space\othertext\content 等
- 其他属性 :list-style(列表样式)\vertical-align\cursor\z-index(层叠顺序)\zoom 等
css 命名基本单词规范
1.页面结构
- 容器:
container
/wrap
- 整体宽度:
wrapper
- 页头:
header
- 内容:
content
- 侧栏:
sidebar
- 栏目:
column
- 中间内容:
center
2.导航
- 导航:
nav
- 主导航:
mainNav
/main_nav
- 子导航:
subNav
/sub_nav
- 顶导航:
topNav
/top_nav
- 边导航:
sideBar
/side_bar
- 左导航:
leftSideBar
/left_side_bar
- 右导航:
righSideBar
/righ_side_bar
- 边导航图标:
sidebarIcon
side_bar_icon
- 菜单:
menu
- 子菜单:
subMenu
sub_menu
- 标题:
title
3.功能
- 标志:
logo
- 登陆:
login
- 登录条:
loginbar
- 注册:
regsiter
- 产品:
products
- 产品价格:
products_prices
- 产品评论:
products_review
- 编辑评论:
editor_review
- 最新评论:
news_release
- 广告/标语:
banner
- 摘要:
summary
- 生产商:
publisher
- 缩略图:
screenshot
- 常见问题:
faqs
- 关键词:
keyword
- 博客:
blog
- 论坛:
forum
- 搜索:
search
- 搜索输入框:
search_input
- 搜索输出:
search_output
- 搜索结果:
search_results
- 加入我们:
joinus
- 状态:
status
- 按钮:
btn
- 滚动:
scroll
4.视图: view
5.滚动
- 视图:
scroll-view
- 标签页:
tab
- 文章列表:
list
- 提示信息:
msg
/message
- 当前的:
current
- 小技巧:
tips
- 皮肤:
skin
- 充值:
pay
- 活动:
activities
- 推广:
promotion
- 公告:
announcement
- 排行:
ranking
- 公司简介:
company_profile
- 公司设备:
equipment
- 公司荣誉:
glories
- 企业文化:
culture
- 企业规模:
scale
- 营销网络:
sales_network
- 组织机构:
organization
- 技术力量:
technology
- 分支机构:
branches
- 经营理念:
operation_principle
- 经理致辞:
manager_oration
- 发展历程:
development_history
- 工程案例:
engineering_projects
- 分类浏览:
browse_by_category
- 应用领域:
application_fields
- 人力资源:
human_resource_hr
- 领导致辞:
leader_oration
- 客户留言:
customer_message
- 客户服务:
customer_service
- 您的要求:
your_requirements
- 销售信息:
sales_information
- 招商:
enterprise_establishing
- 教育培训:
education_training
- 合作加盟:
joinIn_cooperation
- 产品描述:
products_description
- 业务范围:
business_scope
- 产品销售:
sales_sales
- 联系我们:
contact_us
- 信息发布:
information
- 返回首页:
homepage
- 产品定购:
order
- 电子商务:
e_business
- 版权所有:
copy_right
- 友情连结:
hot_link
- 行业新闻:
trade_news
- 行业动态:
trends
- 邮编:
postal_code_zipcode
- 新闻动态:
news_trends
- 公司名称:
company_name
- 销售热线:
sales_hotline
- 联系人:
contact_person
- 建设中:
in_construction
- 证书:
certificate
- 地址:
address
- 电话:
tel
- 传真:
fax
- 产品名称:
product_name
- 产品说明:
description
- 价格:
price
- 品牌:
brand
- 规格:
specification
- 尺寸:
size
- 生产厂家:
manufacuturer
- 型号:
model
- 产品标号:
item_no
- 技术指标:
technique_data
- 产品描述:
description
- 产地:
production_place
- 用途:
application
- 论坛:
forum
- 在线订购:
on_line_order
- 招标:
bidInviting
- 综述:
general
- 业绩:
achievements
- 大事:
great_event
- 动态:
trends
- 服务:
service
- 投资:
investment
- 行业:
industry
- 规划:
programming
- 环境:
environment
- 发送:
delivery
- 提交:
submit
- 重写:
reset
- 社区:
community
- 业务:
business
- 在线调查:
online_inquiry
- 下载中心:
download
- 意见反馈:
feedback
- 常见问题:
faq
- 中心概况:
general_profile
- 游乐园:
amusement_park
- 专题报道:
special_report
- 图标:
icon
- 注释:
note
- 指南:
guild
- 服务:
service
- 热点:
hot
- 新闻:
news
- 下载:
download
- 投票:
vote
- 商标:
label
/branding
- 当前位置:
breadcrumb
/loc
- 购物车:
shop
- 标签:
tag
- 信誉:
siteinfo_credits
- 网站信息:
siteinfo
- 法律声明:
siteinfo_legal
- 合作伙伴:
partner
- 友情链接:
friendlink
- 版权:
copyright
class 命名规范
分类式命名法(在前端组件优化下尤为重要)
- 布局(grid)(
.g-
):将页面分割为几大块,通常有头部,主体,主栏,侧栏,尾部等。 - 模块(module)(
.m-
):通常是一个语义化可以重复使用的较大整体,比如导航,登录,注册等。 - 元件(unit)(
.u-
):通常是一个不可再分的较为小巧的个体,通常被重复用于各种模块中,例如按钮,输入框。 - 功能(function)(
.f-
):为了方便一些重用样式的使用,我们将这些使用频繁的样式剥离出来,按照需求使用,通常这些选择器具有固定样式表现,比如清除浮动等(不可滥用)。 - 状态(
.z-
):为状态样式加入前缀,统一标识,方便识别,它只能组合使用或作为后代出现。 - javascript(
.j-
):j-被专用与 JS 获取节点,请勿使用 j-定义样式。 - class 名称中只能出现小写字母和破折号”-“。破折号应当用于相关 class 的命名(类似于空间命名)例如: .btn 和.btn-xxx。
- 避免过度任意的简写。例如:
.btn
代表 button,但是.s
不能代表任何意思。 - class 名称应当尽可能短,并且意义明确。
- 使用有意义的名称,使用有组织或目的地明确的名称,不要使用表现形式的名称。
- 基于最近的父 class 或基本(base)class 作为新 class 的前缀。例如:父 class 为.btn 则子 class 为.btn-xxx。
- 使用 j-*class 来标识行为(与样式相对),并且不要将这些 class 包含到 css 文件中。
服务端 nodejs/java 命名规则
类型(名) | 约束 | 例 |
---|---|---|
项目 | 全部小写 多个单词用中划线分隔‘-’ | spring-cloud |
包 | 全部小写 | com.alibaba.fastjson |
类 | 单词首字母大写 | Feature , FieldDeserializer |
变量 | 首字母小写 多个单词组成时, 除首个单词 其他单词首字母都要大写 | password , userName |
常量 | 全部大写,多个单词,用’_‘分隔 | CACHEEXPIREDTIME |
方法 | 同变量 | read() , getById(Long id) |
*包的命名
格式:组织类型+组织名称+项目名称+功能名称
/ 【前缀】 【发起者名】【项目名】【模块名】
,点分隔符之间有且仅有一个自然语义的英文单词或者多个单词自然连接到一块,包名中不要有大写字母和下划线,最好也不要有数字。
包名统一使用单数形式,如果类命有复数含义,则可以使用复数形式。
前缀 | 例 | 含义 |
---|---|---|
indi 或 onem |
indi.发起者名.项目名.模块名.…… |
个体项目 个人发起,但非自己独自完成 可公开或私有项目, copyright 主要属于发起者。 |
pers |
pers.个人名.项目名.模块名.…… |
个人项目 指个人发起,独自完成, 可分享的项目 copyright 主要属于个人 |
priv |
priv.个人名.项目名.模块名.…… |
私有项目,指个人发起,独自完成 非公开的私人使用的项目, copyright 属于个人。 |
team |
team.团队名.项目名.模块名.…… |
团队项目,指由团队发起 并由该团队开发的项目 copyright 属于该团队所有 |
顶级域名 | com.公司名.项目名.模块名.…… |
公司项目 copyright 由项目发起的公司所有 |
接口的名称
不要以I
为开头。
如果以~able
结尾表示具备某种能力,例如 Cloneable
和 Runnable
。
类的命名
- 类名使用大驼峰命名形式,类命通常时名词或名词短语,接口名除了用名词和名词短语以外,还可以使用形容词或形容词短语,如
Cloneable
,Callable
等,表示实现该接口的类有某种功能或能力。对于测试类则以它要测试的类开头,以Test
结尾,如HashMapTest
。 - 对于一些特殊特有名词缩写也可以使用全大写命名,比如 XMLHttpRequest,不过通常认为缩写三个字母以内都大写,超过三个字母则按照要给单词算。这个没有标准,如阿里巴巴中fastjson用 JSONObject 作为类命,而 google 则使用 JsonObjectRequest 命名,对于这种特殊的缩写,原则是组织统一就好。
- 不要以
Base
作为开头或者结尾,基类选用的词汇应该是具有通用意义的名称,例如Model
、View
、Control
等。 - 子类的命名如果继承父类的名称则会好懂,例如
SoftKeyboard extends AbstractKeyboard
。 - 抽象类前面可以增加
Abstract
开头,这是当有一个 Concrete 类存在,而无法直接使用名称为抽象类命名时使用的。例如AbstractInputMethodService
。 - 兄弟类之间要有明显的区别式赐予,如
SoftKeyboard
、HardKeyboard
。
属性(类) | 约束 | 例 |
---|---|---|
抽象 | Abstract 或 Base 开头 |
BaseUserService |
枚举 | Enum 作为后缀 |
OSTypeEnum |
工具 | Utils 作为后缀 |
StringUtils |
异常 | Exception 结尾 |
RuntimeException |
接口实现 | 接口名+ Impl |
UserServiceImpl |
领域模型相 | DO /DTO /VO /DAO |
正例:UserDAO 反例:UserDao |
设计模式相关 | Builder ,Factory 等 |
当使用到设计模式时 要使用对应的设计模式作为后缀 如 ThreadFactory |
处理特定功能 | Handler ,Predicate Validator |
表示处理器,校验器,断言 这些类工厂还有配套的方法名 如 handle ,predicate ,validate |
测试 | Test 后缀 |
UserServiceTest 表示用来测试 UserService 类的 |
MVC 分层 | Controller ,Service ServiceImpl ,DAO 后缀 |
UserManageController UserManageDAO |
注解的命名(装饰器)
一定要考虑被使用时的样子。
原则
好的命名增加代码阅读性,代码的命名往往有严格的限制。而注解不同,程序员往往可以自由发挥,但并不意味着可以为所欲为之胡作非为。优雅的注解通常要满足三要素。
-1. Nothing is strange. 没有注解的代码对于阅读者非常不友好,哪怕代码写的在清楚,阅读者至少从心理上会有抵触,更何况代码中往往有许多复杂的逻辑,所以一定要写注解,不仅要记录代码的逻辑,还有说清楚修改的逻辑。
-2. Less is more. 从代码维护角度来讲,代码中的注解一定是精华中的精华。合理清晰的命名能让代码易于理解,对于逻辑简单且命名规范,能够清楚表达代码功能的代码不需要注解。滥用注解会增加额外的负担,更何况大部分都是废话。
-3. Advance with the time. 注解应该随着代码的变动而改变,注解表达的信息要与代码中完全一致。通常情况下修改代码后一定要修改注解。
注解格式
注解大体上可以分为两种,一种是 jsdoc/javadoc 注解,另一种是简单注解。参与同一项目开发的同学,尽量设置成相同的注解模板。
枚举的命名
要考虑到声明和调用时的情形。
方法的命名
方法命名采用小驼峰的形式,首字小写,往后的每个单词首字母都要大写。和类名不同的是,方法命名一般为动词或动词短语,与参数或参数名共同组成动宾短语,即动词 + 名词。一个好的函数名一般能通过名字直接获知该函数实现什么样的功能。
- 动词+名词式命名的基本原则:要选择合适的动词,动词是方法的灵魂;其次要列明动作的对象,至于动作的修饰符(副词)或者对象的修饰语(定语),放到参数列表里就好了。
- 方法名称和返回值之间的关系:如果返回值有可能是个列表,那么方法所带有的名词最好就是复数形式;如果返回值是布尔型的,那么就要用
is
/can
/need
/has
/contains
等开头;如果返回值是确定类型的,那么该类型的名字有可能需要出现在方法名称里;如果返回值是个不确定类型的,那么 Object 或者父类名称是一个代替;如果是个 Getter,那么 get 对象的名称就是其名词部分。 - 考虑被调用时的样子
- “执行”动词的使用:
doLogin
意味着authenticate
,doRegister
意味着createUser
,doEdit
就是 Save`。 - 介词的使用:
by
、with
、and
、after
等 - 其他:命名不要有下划线,不要有临时字符。
返回真伪值的方法
注:pre-
prefix 前缀,suf-
suffix 后缀,alo-
alone 单独使用
位置 | 单词 | 意义 |
---|---|---|
pre | is |
对象是否符合期待的状态 |
pre | can |
对象能否执行所期待的动作 |
pre | should |
调用方执行某个命令或方法是好还是不好、应不应该, 或者说推荐还是不推荐 |
pre | has |
对象是否持有所期待的数据和属性 |
pre | needs |
调用方是否需要执行某个命令或方法 |
用来检查的方法
单词 | 意义 | 例 |
---|---|---|
ensure |
检查是否为期待的状态不是则抛出异常或返回 error code | ensureCapacity |
validate |
检查是否为正确的状态不是则抛出异常或返回 error code | validateInputs |
按需求才执行的方法
位置 | 单词 | 意义 | 例 |
---|---|---|---|
suf | IfNeeded |
需要的时候执行不需要则什么都不做 | drawIfNeeded |
pre | might |
同上 | mightCreate |
pre | try |
尝试执行失败时抛出异常或是返回 errorcode | tryCreate |
suf | OrDefault |
尝试执行失败时返回默认值 | getOrDefault |
suf | OrElse |
尝试执行失败时返回实际参数中指定的值 | getOrElse |
pre | force |
强制尝试执行 error 抛出异常或是返回值 | forceCreate , forceStop |
异步相关方法
位置 | 单词 | 意义 | 例 |
---|---|---|---|
pre | blocking |
线程阻塞方法 | blockingGetUser |
suf | InBackground |
执行在后台线程 | doInBackground |
suf | Async |
异步方法 | sendAsync |
suf | Sync |
同步方法 | sendSync |
pre / alo | schedule |
Job 和 Tas k 放入队列 | schedule , scheduleJob |
pre / alo | post |
同上 | postJob |
pre / alo | execute |
执行异步 或同步方法 | execute , executeTask |
pre / alo | start |
同上 | start , startJob |
pre / alo | cancel |
停止异步方法 | cance , cancelJob |
pre / alo | stop |
同上 | stop , stopJob |
回调方法
位置 | 单词 | 意义 | 例 |
---|---|---|---|
pre | on |
事件发生时执行 | onCompleted |
pre | before |
事件发生前执行 | beforeUpdate |
pre | pre |
同上 | preUpdate |
pre | will |
同上 | willUpdate |
pre | after |
事件发生后执行 | afterUpdate |
pre | post |
同上 | postUpdate |
pre | did |
同上 | didUpdate |
pre | should |
确认事件是否可以执行 | shouldUpdate |
操作对象生命周期的方法
单词 | 意义 | 例 |
---|---|---|
initialize |
初始化或延迟初始化使用 | initialize |
pause |
暂停 | onPause , pause |
stop |
停止 | onStop , stop |
abandon |
销毁的替代 | abandon |
destroy |
同上 | destroy |
dispose |
同上 | dispose |
与集合操作相关的方法
单词 | 意义 | 例 |
---|---|---|
contains |
是包含指定对象相同的对象 | contains |
add |
添加 | addJob |
append |
添加 | appendJob |
insert |
插入到下标 n | insertJob |
put |
添加与 key 对应的元素 | putJob |
remove |
移除元素 | removeJob |
enqueue |
添加到队列的最末位 | enqueueJob |
dequeue |
从队列中头部取出并移除 | dequeueJob |
push |
添加到栈头 | pushJob |
pop |
从栈头取出并移除 | popJob |
peek |
从栈头取出但不移除 | peekJob |
find |
寻找符合条件的某物 | findById |
与数据相关的方法
单词 | 意义 | 例 |
---|---|---|
create |
新创建 | createAccount |
new |
新创建 | newAccount |
from |
从既有的某物新建或是从其他的数据新建 | fromConfig |
to |
转换 | toString |
update |
更新既有某物 | updateAccount |
load |
读取 | loadAccount |
fetch |
远程读取 | fetchAccount |
delete |
删除 | deleteAccount |
remove |
删除 | removeAccount |
save |
保存 | saveAccount |
store |
保存 | storeAccount |
commit |
保存 | commitChange |
apply |
保存或应用 | applyChange |
clear |
清除或是恢复到初始状态 | clearAll |
reset |
清除或是恢复到初始状态 | resetAll |
函数的第一规则是要短小,第二条规则是还要更短小
最后
一个命名插件:
- 在线:https://unbug.github.io/codelf/,不过不稳定,中文版用了有道翻译api有次数限制。
Github:https://github.com/unbug/codelf
相关链接
- 《Python 工匠》案例技巧与工程实践
- 《编写可读代码的艺术》
- 《会说话的代码》
- 《代码整洁之道》
- 《编程的原则》
- https://www.yuque.com/iv8gga/qgf69v/296ea151c0a1d5bd475f8b3c5ed1a0f4
- https://juejin.cn/post/6995342820512890893
- https://jimmysong.io/eng-practices/docs/review/reviewer/looking-for/#%E5%91%BD%E5%90%8D
Author
My name is Micheal Wayne and this is my blog.
I am a front-end software engineer.
Contact: michealwayne@163.com