代码三部曲,最全代码治理知识体系(中)

1.问题

  • 1、代码管理是什么,包含哪些内容?

  • 2、如何建设合适的代码仓库,如何规范治理代码仓库?

  • 3、如何应用版本控制工具,选择合适的分支策略,适应不同的开发模式?

  • 4、项目开源需要注意哪些环节?

  • 5、编码规范又有哪些通用的准则,如何使用工具提升效率?

  • 6、代码审查的意义是什么,如何进行有效的代码审查?

  • 7、代码审查需要检查哪些清单,有哪些步骤?

2.关键词

代码管理,编码规范,代码审查,源码,仓库,版本控制,修订,冲突,分支,合并,脚本,权限,提交规范,提交,工具,开源,编码准则,版权,命名,注释,规约,扫描工具,漏洞,流程,审查步骤

关注公众号《编程原理》,回复“代码”获取最全代码治理知识体系思维导图

51dac0be810c40fc9e05a00c77a5b913.jpeg

3.全文概要

本文试图在代码领域里面建立一套完整的知识体系,涵盖了代码管理中的仓库建设与治理,版本控制的操作与原理,在夯实代码管理服务的基础上,谈谈如何编写出规范靠谱的代码,介绍一系列业界推崇的编码规范,然后再介绍代码评审的一套方法论。在代码管理,规范,评审三大环节形成闭环,解释了代码上下游的知识结构,从而对代码运营有进一步的理解。

4.编码规范

如果从唯物层面,代码管理我们已经梳理了整个流程,按不同层次进行了阐述,这可以理解为物质层面的管理。至于代码写得好坏我们全然没提到,空有代码管理是不够的,所以我们在这节要重点介绍编码规范,在精神层面对代码进行约束,从而提高代码资产的价值。

由于编码语言和语言模式各有不同,需要兼顾不同语言的特点,所以这里并不打算长篇累牍的介绍不同语言的编码规范,而是抽象出大部分共同需要关注的关键点。

4.1编码准则

通常成熟的软件开发组织会希望程序员保持某种定义良好的标准编码风格,即编码标准。刚开始可能不同企业有不同的标准,但是随着业界现在企业的引领和实践,慢慢的会形成业界通用的一些基本规范,但是这种非事实标准的编码准则无法强制执行,但是对我们指定科学的编码准则也是很有意义的:

  • 编码标准使不同工程师编写的代码具有统一的外观

  • 提高了代码的可读性和可维护性,降低了复杂性

  • 有助于代码重用,并且有助于轻松检测错误

  • 促进了良好的编程习惯

  • 并提高了程序员编码效率

  • 有助于在早期阶段检测代码错误

  • 能通过工具自动化监测代码缺陷

4.2版本规范

进入编码之前我们会给项目工程分配版本,版本不仅仅是区分不同阶段的软件产品,好的版本定义可以传递更多高质量有效信息。通常版本号会呈现出以下格式:
主版本号.次版本号.修订号

版本号递增规则如下:

  • 次版本号,做了向下兼容的功能性新增

  • 修订号,做了向下兼容的问题修正

  • 先行版本号及版本编译元数据可以加到“主版本号.次版本号.修订号”的后面,作为延伸

具体的版本号变化规则我们可以参考语义化版本Semantic Versioning给出的一些规则。使用语义化版本控制的软件必须(MUST)定义公共 API。该API可以在代码中被定义或出现于严谨的文件内。无论何种形式都应该力求精确且完整。

  • 标准的版本号必须采用 X.Y.Z 的格式

  • 标记版本号的软件发行后,禁止改变该版本软件的内容

  • 主版本号为零(0.y.z)的软件处于开发初始阶段,一切都可能随时被改变

  • 1.0.0的版本号用于界定公共API的形成

  • 修订号Z(x.y.Z | x > 0)必须在只做了向下兼容的修正时才递增

  • 次版本号Y(x.Y.z | x > 0)必须在有向下兼容的新功能出现时递增

  • 主版本号 X(X.y.z | X > 0)必须在有任何不兼容的修改被加入公共API时递增

以上只是列举了语义化版本常用的一些规则,更多规则可以前往官网阅读。

4.4文件规范

编码的独立单元通常是以文件来划分,那么如果对文件进行规范也是非常重要,一份代码文件通常由文件名,后缀,文件编码格式,版权信息,等一系列元素组成,本节我们将详细剖析一个文件需要注意的那些规范

4.4.1文件名称

首先当然是文件名称,通常源代码文件由它包含的顶级类的大小写敏感的名称以及扩展名组成,如果文件里面有多个类的话则以主类的名称为主。

4.4.2文件编码

通常源文件都是以UTF-8编码,对于其余的非ASCII字符,使用实际的Unicode字符,该选择仅取决于使代码更易于阅读和理解的方法,尽管Unicode会在字符串文字之外进行转义,并且强烈建议不要使用注释。

4.4.3版权信息

在规范好文件名称和编码后,最新开始的应该是文件的许可或版权信息。定义好法律文书等信息后就是文件的头部说明文本。为了更好地理解和维护代码,不同模块的头应遵循一些标准格式和信息。标头格式必须包含多数企业使用的格式:

  • 模块名称

  • 创建模块的日期

  • 模块作者

  • 修改历史

  • 有关模块功能的模块简介

  • 模块中支持的不同功能及其输入输出参数

  • 模块访问或修改的全局变量

4.4.4文件规格

文件规格主要是现在文件文本的列宽和行数限制。Java代码的列数限制为100个字符。“字符”表示任何Unicode代码点。除非另有说明,否则超出此限制的任何行都必须进行换行。通常,有几种有效的方法可以对同一段代码进行换行,需要参考不同语言的语法规则,但是硬性规定的就是100个字符就必须强制换行,以免降低可读性。

4.5命名规范

最重要的一致性规则是命名管理. 命名的风格能让我们在不需要去查找类型声明的条件下快速地了解某个名字代表的含义: 类型,变量,函数,常量,宏,等等。我们大脑中的模式匹配引擎非常依赖这些命名规则。命名规则具有一定随意性, 但相比按个人喜好命名, 一致性更重要,命名的时候尽可能遵循一些原则,尽可能使用描述性的命名,别心疼空间,毕竟相比之下让代码易于新读者理解更重要。不要用只有项目开发者能理解的缩写,也不要通过砍掉几个字母来缩写单词。

4.5.1命名规则

常用的命名规则有以下三种命名法:

  • 匈牙利(Hungarian)命名法:匈牙利命名法通过在变量名前面加上相应的小写字母的符号标识作为前缀,标识出变量的作用域,类型等

  • 骆驼(camel)命名法:骆驼式命令法,正如它的名称所表示的那样,是指混合使用大小写字母来构成变量和函数的名字

  • 帕斯卡(pascal)命名法:与骆驼命名法类似,只不过骆驼命名法是首字母小写,而帕斯卡命名法是首字母大写

4.5.2命名空间

命名空间以小写字母命名,最高级命名空间的名字取决于项目名称,要注意避免嵌套命名空间的名字之间,和常见的顶级命名空间的名字之间发生冲突。顶级命名空间的名称应当是项目名或者是该命名空间中的代码所属的团队的名字。命名空间中的代码,应当存放于和命名空间的名字匹配的文件夹或其子文件夹中。同时注意,不使用缩写作为名称的规则同样适用于命名空间。命名空间中的代码极少需要涉及命名空间的名称,因此没有必要在命名空间中使用缩写。

4.5.3类名定义

所有编程相关的命名均不能以下划线或$结束,具体以业务相关的领域来参考命名。

4.5.4常量命名

常量命名应该全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。

4.5.5变量命名

有意义且易于理解的变量名可以帮助任何人理解使用它的原因。
局部变量应使用驼峰式字母命名,并以小写字母开头,而全局变量名称应以大写字母开头。常量名称只能使用大写字母形成,而且最好避免在变量名中使用数字。

4.5.6函数命名

一般来说, 函数名的每个单词首字母大写 (即 “驼峰变量名” 或 “帕斯卡变量名”), 没有下划线,第一个字母需小写。函数的长度不应太大,冗长的函数很难理解,冗长的函数应该分解为小的功能以完成小的任务。

4.6注释规范

注释虽然写起来很痛苦,但对保证代码可读性至关重要。下面的规则描述了如何注释以及在哪儿注释。当然也要记住:注释固然很重要,但最好的代码应当本身就是文档,有意义的类型名和变量名,要远胜过要用注释解释的含糊不清的名字。

4.6.1函数注释

注释,除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。函数声明处注释的内容:

  • 函数的入参出参

  • 参数是否可以为空

  • 是否存在函数使用上的性能隐患.

  • 如果函数是可重入的, 其同步前提是什么

  • 函数是否做了幂等处理

如果函数的实现过程中用到了很巧妙的方式,或者难以快速理解的逻辑,那么在函数定义处应当加上解释性的注释。

4.6.2变量注释

通常变量名本身足以很好说明变量用途。某些情况下, 也需要额外的注释说明。通常在复杂业务中,需要对上下文做一些说明。

4.6.3待办注释

对那些临时的,短期的解决方案,或已经够好但仍不完美的代码使用 TODO注释,这个时候我们强制用大写来标明注释。在随后的圆括号里写上名字、邮件地址、bug或其它身份标识和与这一 TODO 相关的文档。主要目的是让添加注释的人可根据规范的TODO格式进行查找。添加TODO注释并不意味着需要本人自己来修正,因此当我们加上带有姓名的TODO时,一般都是写上自己的名字。

4.6.4废弃注释

通过废弃注释(DEPRECATED)以标记某接口点已废弃。写上包含全大写的DEPRECATED注释,注释可以放在接口声明前,或者同一行。在DEPRECATED一词后,在括号中留下的名字,邮箱地址以及其他身份标志比如工号之类。修复后的代码应该不会再涉及废弃接口, 需要将该注释移除。

4.7代码规约

下面我们大致讲下编码过程中的一些约定习惯。

4.7.1符号

使用if/else/for/do/while语句,即使方法体是空的或只包含一个声明,开括号之前没有换行,开括号后换行,右括号前的换行符。仅在大括号终止一条语句或终止方法,构造函数构造方法或命名类的主体时,才在右括号后换行。

4.7.2缩进

每次打开新的块或类似块的构造时,缩进量都会增加两个空格。当块结束时,缩进将返回到先前的缩进级别。缩进级别适用于整个块中的代码和注释。正确的缩进对于提高代码的可读性非常重要。为了使代码可读,程序员应适当使用空格。下面给出了一些间距约定:

  • 在两个函数参数之间加逗号后必须有一个空格

  • 每个嵌套块应适当缩进并隔开

  • 程序中每个程序段的开头和结尾都应有适当的缩进

  • 所有花括号应从新行开始,并且花括号末尾的代码也应从新行开始

4.7.3空格

单个空白行也可能出现在它提高可读性的任何地方,例如在将代码组织为逻辑小节的语句之间。不鼓励在类的第一个成员或初始化程序之前,或在最后一个成员或初始化程序之后的空白行。

4.7.4列数

Java代码的列数限制为100个字符。“字符”表示任何Unicode代码点。除非另有说明,否则超出此限制的任何行都必须进行换行,

4.8工具应用

4.8.1命名工具

https://unbug.github.io/codelf/

4.8.2扫描工具

首推阿里巴巴代码规约扫描工具,具体参考官方文档https://github.com/alibaba/p3c/tree/master/idea-plugin

推荐阅读

《代码三部曲,最全代码治理知识体系(上)》

未完待续,敬请期待

《代码三部曲,最全代码治理知识体系(下)》

关注公众号《编程原理》,升级你的编程知识体系

5aa7efb1294074befc0f31d76b8dd7be.jpeg

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值