1.问题
2.关键词代码管理,编码规范,代码审查,源码,仓库,版本控制,修订,冲突,分支,合并,脚本,权限,提交规范,提交,工具,开源,编码准则,版权,命名,注释,规约,扫描工具,漏洞,流程,审查步骤 关注公众号《云时代架构》,回复“代码”获取最全代码治理知识体系思维导图 3.全文概要本文试图在代码领域里面建立一套完整的知识体系,涵盖了代码管理中的仓库建设与治理,版本控制的操作与原理,在夯实代码管理服务的基础上,谈谈如何编写出规范靠谱的代码,介绍一系列业界推崇的编码规范,然后再介绍代码评审的一套方法论。在代码管理,规范,评审三大环节形成闭环,解释了代码上下游的知识结构,从而对代码运营有进一步的理解。 4.代码管理不管初级程序员还是骨灰级的老IT人,最熟悉的莫过于趁手的开发环境IDE和代码。代码甚至是一种信仰般的存在,犹如空气一样,程序员离不开代码,但是对于代码的保护,好像都不能说出个所以然。我们有时候会听说某团队因为代码托管的机器故障而导致整个团队垮掉的新闻,这个时候可能你会觉得这个事件离你很远。但是换个角度来说,如果要从零开始来搭建一套代码管理的系统和一系列的规范流程,是否可以很胸有成竹的办到? 4.1代码资产在软件行业,代码是重要的产出,也是企业组织的核心资产,体现了IT人员的产出,那么如何保护核心资产就是一个重要课题了。正因为代码是核心资产,犹如我们理财一样对财富进行管理,对代码的管理同样需要遵循科学的方法论来操作。 4.4.1 定义首先我们回想一下常见的一种场景,辛辛苦苦码了两小时的文档由于断电化为乌有,即使已经保存了但是反复修改后已经找不到初稿的代码,这时候就有如下的版本管理雏形:
A source code manager (SCM) is a software tool used by teams of programmers to manage source code.SCMs are used to track revisions in software. Each revision is given a timestamp and includes the name of the person who is responsible for the change. Various revisions may be compared, stored, and merged with other revisions. 源代码管理器(SCM)是程序员团队用来管理源代码的软件工具。SCM用于跟踪软件中的修订,每个修订都有一个时间戳,并包括负责更改人员的姓名。可以将各种修订版本与其他修订版本进行比较,存储和合并。 4.4.2 问题最朴素的谈源码管理其实就是要保证源码存在,能用且好用,源码管理一方面是要确保代码不会丢失,也就是要避免删库跑路的极端情况出现,先总结一下代码管理过程中常见的问题:
4.4.3 目标无论是编写简单的应用程序还是大型软件开发上的协作,源代码管理都是软件开发生命周期的重要组成部分。它可以跟踪代码更改,还可以检查需要回滚使用的代码修订历史记录。使用源代码管理,可以与团队合作或隔离代码并进行更改,而不会妨碍团队成员所做的更改,直到代码准备就绪为止。同时可以知道谁进行了更改以及这些更改是什么,甚至故障排除也变得很容易。源代码管理有助于简化软件开发流程。针对上节遇到的问题,我们制定了明确的目标: 4.4.4 原则现在已经制定了清晰的目标,我们还需要遵循一些业界长期积累下来有效的原则,来避免代码管理中出现的疏漏和弯路。 原则:
4.4.5 功能源代码管理我们需要选择合适的软件系统来实现我们的管理意图,通常代码管理系统包含的基本功能:
4.2仓库建设上一节我们在理论上认识了代码管理的概念,从代码的资产化到出现问题和解决问题的思路目标,还有列举管理系统的常用功能,本节将回到实践层面介绍如何搭建一套代码管理系统,及需要注意的方面。 4.2.1代码工具常用的代码管理工具如下:
其中代码管理系统又分为集中式和分布式: 4.2.2仓库搭建随时互联网高速发展的这几年,Git已经大大普及,甚至我们都无需再介绍SVN等集中式代码管理工具,直接就使用Git决定是明智的决定。而我们最熟悉的也莫过于GitHub的服务,对于公开的项目我们可以直接使用GitHub的服务的,但是对于企业仍需自己搭建一套代码管理系统,当然现在越来越多的中小企业直接选择上云托管代码。 常用的代码管理工具:
如果只是实验室性质的或者微型公司起步阶段,那完全可以在本地机器机或者云上自建Git服务,按照官方指导就可以安装Git服务。
但是对于一定规模上的团队就要考虑更加科学高效的协作方式了,由于只有GitLab是开源的,也是最广泛使用的开源系统,因此我们选GitLab作为案例来讲解,论服务GitLab已经非常完善了,而我们搭建需要重点关注的是灾备,热备和冷备,还有高可用方面的。 整体参考如下架构(图片来源于Gitlab) 4.3仓库管理在仓库完成建设后,就是如何科学使用了,好比物流仓库采用各种黑科技无人机建设出来后,如果没科学的规范和管理流程,一样无法实现高效的物流传输,所以本节我们介绍如何高效的使用代码仓库来管理组织我们的代码。 4.3.1分支管理代码仓库从外部看无法就是拿来存代码的数据库,同时要很方便的追溯版本,说白了就是版本控制和代码文件存储。在不谈分支和规范的前提,我们使用Git代码库大可以在master上开发,然后频繁提交代码,后果就是代码版本杂乱无章,问题无法追踪到对应代码版本,经过前人探索,结合Git的功能特性,我们总结出来了分支策略,对应不同的的团队和不同的开发流程。目前比较流程的分支策略有:
Git FlowGit Flow是此列表上最知名的工作流程,它基于两个主要分支:
在开发周期中,使用了各种支持分支:
优点:
缺点:
随着持续部署的交付工作模式的兴起和发展,该模式已经被渐渐抛弃了。 GitHub FlowGitHub Flow是一个轻量级的工作流程。它由GitHub在2011年创建,并遵循以下6条原则:
优点:
缺点:
GitLab FlowGitLab Flow是由GitLab在2014年创建的工作流程。它结合了功能驱动的开发和功能分支以及问题跟踪。GitLab Flow和GitHub Flow之间的最大区别是GitLab Flow中的环境分支 GitLab流基于11条规则:
优点:
缺点:
One FlowOne Flow是一个提议的替代方案。要使用OneFlow,需要满足的主要条件是每个新的生产版本都基于先前的版本。One Flow和Git Flow之间最大的区别在于它没有develop分支。 优点:
缺点:
因此,这是一些最知名的分支工作流程,根据团队的需要,还存在许多其他工作流程,比如阿里的AoneFlow模式,AoneFlow大大简化了分支管理成本,开发步骤如下:
4.3.2规范治理仓库管理的核心分支策略我们介绍完,那么大方向上只需要根据自身团队规模来选择合适策略就足以保障流畅的开发过程,但这个只是我们说的硬件配套,但是代码治理还得深入到细节规范,才能“长治久安”。本节我们介绍代码治理的一些规范和守则,做好了这些软设置,对代码资产也是一种保值升值的体现。 权限管理首先我们要保证代码是安全的,就需要对权限做控制,分别为一下粒度按需进行分配。
Gitlab中的组和项目有三种访问权限:
提交规范代码资产是由一行一行代码堆积而成的,而其中最关键的就是我们在分支工作中向代码库提交一行行的代码。那么这个时候就需要对代码提交这个动作进行约束,而且这种约束不宜繁杂,毕竟这个操作是程序员日常频繁的动作,复杂了不容易执行,所以我们必须制定简明且可复用的约束来保证每次提交的代码质量。
定义好提交代码意图的类型后,记下来要关注的是提交信息的内容,通常需要指定好格式,包含表头,内容,脚注,当然这个并没有固定的格式,根据团队业务特点实现即可,但是如果包含信息量较多的情况,很难保证程序员每次都能按规范来提交,那么这个时候用工具实现自动化就很有必要了,这里我们介绍conventionalcommits提供的脚本来实现commit message的自动生成,由于篇幅限制这里就不展开说明,具体可以上官网根据指示安装。 提交准则我们选择了科学的分支策略,权限管理分配好,同时提交信息也工整规范,但也耐不住一天提交个二三十次,或者憋了好几天提交一次那种,或者更甚的提交的代码不全导致编译问题之类,所以指定提交准则就是要规避这些问题,让代码提交有一个良好的频率和质量保障。 我们对可提交代码大概分为以下标准:
编译通过 < 运行通过 < 单测通过 < 验证通过 以上就是代码仓库管理的一些规范和准则,做好了这些前提后,后面就按部就班即可,也就是前人种树后人乘凉,战略上调整好方向,下一节讲的就是战术上怎么用好版本控制工具。 4.4工具应用提代码管理的时候很多同学会直接谈版本控制,而忽略了上文包含的分支策略,代码准则等规范,而这节我们介绍的是版本控制工具的核心原理和使用技巧,鉴于现在Git的流行程度,我们大可以直接跳过即将进入博物馆SVN。上文已经介绍了代码仓库的搭建步骤包括Git服务的安装和分布式服务的部署,本节主要从版本控制的原理,分支管理和核心操作技巧三个方面进行介绍。 4.4.1底层原理在学习底层原理之前,我们思考下如果自己动手来写个版本管理软件,该如何入手? 数据结构我习惯把复杂的东西通过生活经验直观的转换为简单容易的理解,刚接触Git那会,对比SVN的使用确实有很多新的知识和技能需要学习,虽说现在SVN那套基本也忘光了,但是我们还是需要从根基上了解Git是个怎样的东西。从简单的逻辑出发,版本控制无非就是记录每次操作,提供操作对比差异,也就是把数据看作对文件系统的快照流,每次提交更新时,对相关文件制作一个快照并保存这个快照的索引。这一点跟SVN记录变更的增量有所差别。 大白话来讲Git是一个软件,启动运行时在操作系统里面起来一个进程,作用用于内容寻址,本质是是一个管理文件的进程,更进一步讲Git其实就是个数据库,只不过存储的内容是文件。本质是Git也是一个非典型的nosql数据库,这里我们类别MongoDB这样的数据库,因为Git底层就是通过key-value的方式来存储文件和寻址的,非常朴素的结构,而核心就是如何科学的组织这一堆KV键值对的关系。 先来看一个空代码库里面有什么东西 $ ls -l 在创建一个git代码库的时候会自动初始化一个.git目录,这个也是Git数据包含的全部内容,而我们只需关注:HEAD 文件、(尚待创建的)index 文件,和 objects 目录、refs 目录。这些条目是 Git 的核心组成部分。
组织结构弄清楚Git数据库的数据结构后,我们关心的是Git如何对数据进行读写。接下来我们可以试着创建一个git代码库,然后进行最原始的操作
通过简单的两行命令,我们就实现了Git的底层操作,确实简单,这个也实现了文件的读写,我们看到hash-object这个命令就是以键值对的方式存储,返回一个sha-id作为文件的唯一标识。 接下来我们介绍一下键值对中object的类型,其实也很好理解,如果全是一堆键值对毫无关联的散落在objects的目录下,那么寻址肯定是很低效而且不可管理,所以我们需要对文件的组织方式进行研究。其实也很简单,就是通常的数据结构,目前对文件的格式有两种类型:blob和tree。普通的文件是blob,tree类型就是组织blob形成的树状文件。 (图片来源Git官网) 从上图我们可以知道Git的文件结构就是由tree类型的文件串起来的。 快照管理弄清楚Git文件库包含什么,并且知道文件如何关联起来后,这个时候只能静态的存储工作文件,这节我们弄清楚不同版本之间是如何关联起来。其实想想也是很简单的事情,无非就是每次提交都把有变更的文件使用快照保存起来,我们用快照这个词说明每次提交都有一个新的版本,当然这样你会怀疑是不是多次提交后Git库会变得冗余。其实我们不需要担心这个问题,因为Git会判断那些没变更的文件,存放的是文件的“地址指针”,寻找的时候通过指针链来找到具体的文件内容,如下图呈现了多次提交产生的快照。
(图片来源git官网) 工作区域了解了以上的知识储备后,我们可以很轻松的区分Git的工作区域,我们用一张图来概括即可。 4.4.2分支操作在我们学习了Git底层工作原理后,再来理解分支会有很大的帮助。同时我们在仓库管理一节也明确了开发分支的策略,相当于在战略层面确定了分支的模式,本节是战术上介绍分支运用的过程。 创建分支分支创建只需要一个很简单的命令 $ git branch new Git背后是怎么创建新分支的呢?其实很简单,它只是为你创建了一个可以移动的新的指针,这会在当前所在的提交对象上创建一个指针,所以速度很快。 切换分支切换分支其实就是在.git/HEAD文件里面指定工作区域的分支,可以随时切换,结构如下图 合并分支多个分支最终总是需要合并后再发布,这个时候就需要把多个分支的指针合并起来。 4.4.3命令脚本最后一步就是介绍命令脚本了,但是本文不是针对Git的专有教程,不打算全面仔细的讲解所有脚本,篇幅限制而且大家去官网查询脚本操作手册即可。本节重点介绍核心的几个脚本的使用方法。由于现在git客户端工具也已经有很长足的改善了,很多同学可能直接在Git的UI客户端直接操作,但了解这些核心脚本还是很有帮助的。 reset很多时候我们需要对提交过的代码进行回滚,默认调用git reset具有的隐含参数—mixed和HEAD。这意味着执行git reset等同于执行git reset —mixed HEAD。以这种形式HEAD指定的提交。代替HEAD任何Git SHA-1提交哈希都可以使用。
revert如果git revert是撤消更改的“安全”方法,则可以将其git reset视为危险的方法。确实有失去与一起工作的风险git reset。Git reset永远不会删除提交,但是,提交可能会变成“孤立的”,这意味着没有从引用访问它们的直接路径。通常可以使用来找到并还原这些孤立的提交git reflog。Git运行内部垃圾收集器后,将永久删除所有孤立的提交。默认情况下,Git配置为每30天运行一次垃圾收集器。使用此工具时必须小心,因为它是可能会丢失工作的仅有的Git命令之一。 cherry-pickgit cherry-pick是一个功能强大的命令,它允许通过引用选择任意Git提交并将其附加到当前工作的HEAD上。Cherry Picking是从分支中选择提交并将其应用于另一个的行为。git cherry-pick对于撤消更改很有用。假设一次提交在错误的分支进行提交的,则可以切换到正确的分支,然后选择提交应属于的位置。 下面我们介绍下cherry-pick的一些使用场景:
下面演示下如何使用git cherry-pick,先假设我们有一个具有以下分支状态的存储库:
git cherry-pick用法很简单,可以像这样执行: git cherry-pick commitSha 在此示例中,commitSha是提交引用。可以使用找到提交记录git log。首先,我们确保我们在master分支机构上工作
然后,使用以下命令执行cherry-pick: git cherry-pick f 一旦执行,我们的Git历史将如下所示:
f提交已成功进入功能分支Cherry Picking是一个功能强大且方便的命令,在某些情况下非常有用。但并不是用来代替代替git merge或git rebase。 rebaserebase是将更改从一个分支集成到另一个分支的方法。rebase将所有更改压缩到单个“补丁”中。然后将补丁集成到目标分支中。rebase是两个Git实用脚本之一,专门用于将代码变更从一个分支集成到另一个分支。另一个变更集成实用程序是git merge。合并始终是向前移动的更改记录。rebase本身有2种主要模式:“手动”和“交互”模式。 stashgit stash暂时隐藏对工作副本所做的更改,以便我们可以处理其他内容,然后再返回并稍后重新应用它们。
值得注意的是,该存储区在Git存储库本地;推送时,存储的资源不会转移到服务器。通常在以下场景会使用到:
4.5开源管理关于开源项目,开源是促进生产力的核动力,相信很多同学都是开源社区的簇拥,或多或少参与过开源项目的建设。至于如何开源一个项目,也是技术人毕生的一个追求,开源一个项目很简单,可能发布在Github上面就可以了,但是要做出一个规范的开源项目,并且能提交到类似Apache基金会上的就不是那么容易了。 4.5.1设定目标目标可以帮助我们弄清楚该做什么,不该说什么,以及在哪里需要别人的帮助,为什么我要开源这个项目?这个问题没有正确的答案。您可能为一个项目或具有不同目标的不同项目有多个目标。 4.5.2开源许可开源许可证可确保其他人可以使用,复制,修改和回馈我们的项目,而不会造成影响。它还可以保护我们免受棘手的法律问题困扰。启动开源项目时,必须包含许可证。当然法律工作没有多大的乐趣,不过我们可以将现有许可证复制并粘贴到代码库中,MIT,Apache 2.0和GPLv3是最受欢迎的开源许可证,但还有其他选择。在GitHub上创建新项目时,可以选择许可证。包括开源许可证将使我们的GitHub项目成为开源。 4.5.3自述文件自述文件所做的不只是解释如何使用我们的项目。他们还解释了为什么我们的项目很重要,以及用户可以使用它做什么。在自述文件中,尝试回答以下问题:
4.5.4贡献准则CONTRIBUTING文件将告诉我们的用户如何参与您的项目,可能包括以下信息:
4.5.1行为守则最后,行为准则有助于为项目参与者设置行为的基本规则。如果要为社区或公司启动一个开源项目,那么这特别有价值。行为准则能够促进健康,建设性的社区行为,从而减轻维护者的压力。 4.5.6项目命名选择一个易于记忆的名称,理想情况下,可以让我们对该项目的用途有所了解。在项目的整个生命周期中,会包括很多事情:自述文件,教程,社区文档,对问题的响应,甚至是新闻通讯和邮件列表。无论是正式文档还是随便一封电子邮件,我们的写作风格都是项目品牌的一部分。 4.5.7发布清单文档:
5.编码规范如果从唯物层面,代码管理我们已经梳理了整个流程,按不同层次进行了阐述,这可以理解为物质层面的管理。至于代码写得好坏我们全然没提到,空有代码管理是不够的,所以我们在这节要重点介绍编码规范,在精神层面对代码进行约束,从而提高代码资产的价值。 由于编码语言和语言模式各有不同,需要兼顾不同语言的特点,所以这里并不打算长篇累牍的介绍不同语言的编码规范,而是抽象出大部分共同需要关注的关键点。 5.1编码准则通常成熟的软件开发组织会希望程序员保持某种定义良好的标准编码风格,即编码标准。刚开始可能不同企业有不同的标准,但是随着业界现在企业的引领和实践,慢慢的会形成业界通用的一些基本规范,但是这种非事实标准的编码准则无法强制执行,但是对我们指定科学的编码准则也是很有意义的:
5.2版本规范进入编码之前我们会给项目工程分配版本,版本不仅仅是区分不同阶段的软件产品,好的版本定义可以传递更多高质量有效信息。通常版本号会呈现出以下格式: 版本号递增规则如下:
具体的版本号变化规则我们可以参考语义化版本Semantic Versioning给出的一些规则。使用语义化版本控制的软件必须(MUST)定义公共 API。该API可以在代码中被定义或出现于严谨的文件内。无论何种形式都应该力求精确且完整。
以上只是列举了语义化版本常用的一些规则,更多规则可以前往官网阅读。 5.3文件规范编码的独立单元通常是以文件来划分,那么如果对文件进行规范也是非常重要,一份代码文件通常由文件名,后缀,文件编码格式,版权信息,等一系列元素组成,本节我们将详细剖析一个文件需要注意的那些规范 5.3.1文件名称首先当然是文件名称,通常源代码文件由它包含的顶级类的大小写敏感的名称以及扩展名组成,如果文件里面有多个类的话则以主类的名称为主。 5.3.2文件编码通常源文件都是以UTF-8编码,对于其余的非ASCII字符,使用实际的Unicode字符,该选择仅取决于使代码更易于阅读和理解的方法,尽管Unicode会在字符串文字之外进行转义,并且强烈建议不要使用注释。 5.3.3版权信息在规范好文件名称和编码后,最新开始的应该是文件的许可或版权信息。定义好法律文书等信息后就是文件的头部说明文本。为了更好地理解和维护代码,不同模块的头应遵循一些标准格式和信息。标头格式必须包含多数企业使用的格式:
5.3.4文件规格文件规格主要是现在文件文本的列宽和行数限制。Java代码的列数限制为100个字符。“字符”表示任何Unicode代码点。除非另有说明,否则超出此限制的任何行都必须进行换行。通常,有几种有效的方法可以对同一段代码进行换行,需要参考不同语言的语法规则,但是硬性规定的就是100个字符就必须强制换行,以免降低可读性。 5.4命名规范最重要的一致性规则是命名管理. 命名的风格能让我们在不需要去查找类型声明的条件下快速地了解某个名字代表的含义: 类型,变量,函数,常量,宏,等等。我们大脑中的模式匹配引擎非常依赖这些命名规则。命名规则具有一定随意性, 但相比按个人喜好命名, 一致性更重要,命名的时候尽可能遵循一些原则,尽可能使用描述性的命名,别心疼空间,毕竟相比之下让代码易于新读者理解更重要。不要用只有项目开发者能理解的缩写,也不要通过砍掉几个字母来缩写单词。 5.4.1命名规则常用的命名规则有以下三种命名法:
5.4.2命名空间命名空间以小写字母命名,最高级命名空间的名字取决于项目名称,要注意避免嵌套命名空间的名字之间,和常见的顶级命名空间的名字之间发生冲突。顶级命名空间的名称应当是项目名或者是该命名空间中的代码所属的团队的名字。命名空间中的代码,应当存放于和命名空间的名字匹配的文件夹或其子文件夹中。同时注意,不使用缩写作为名称的规则同样适用于命名空间。命名空间中的代码极少需要涉及命名空间的名称,因此没有必要在命名空间中使用缩写。 5.4.3类名定义所有编程相关的命名均不能以下划线或$结束,具体以业务相关的领域来参考命名。 5.4.4常量命名常量命名应该全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。 5.4.5变量命名有意义且易于理解的变量名可以帮助任何人理解使用它的原因。 5.4.6函数命名一般来说, 函数名的每个单词首字母大写 (即 “驼峰变量名” 或 “帕斯卡变量名”), 没有下划线,第一个字母需小写。函数的长度不应太大,冗长的函数很难理解,冗长的函数应该分解为小的功能以完成小的任务。 5.5注释规范注释虽然写起来很痛苦,但对保证代码可读性至关重要。下面的规则描述了如何注释以及在哪儿注释。当然也要记住:注释固然很重要,但最好的代码应当本身就是文档,有意义的类型名和变量名,要远胜过要用注释解释的含糊不清的名字。 5.5.1函数注释注释,除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。函数声明处注释的内容:
如果函数的实现过程中用到了很巧妙的方式,或者难以快速理解的逻辑,那么在函数定义处应当加上解释性的注释。 5.5.2变量注释通常变量名本身足以很好说明变量用途。某些情况下, 也需要额外的注释说明。通常在复杂业务中,需要对上下文做一些说明。 5.5.3待办注释对那些临时的,短期的解决方案,或已经够好但仍不完美的代码使用 TODO注释,这个时候我们强制用大写来标明注释。在随后的圆括号里写上名字、邮件地址、bug或其它身份标识和与这一 TODO 相关的文档。主要目的是让添加注释的人可根据规范的TODO格式进行查找。添加TODO注释并不意味着需要本人自己来修正,因此当我们加上带有姓名的TODO时,一般都是写上自己的名字。 5.5.4废弃注释通过废弃注释(DEPRECATED)以标记某接口点已废弃。写上包含全大写的DEPRECATED注释,注释可以放在接口声明前,或者同一行。在DEPRECATED一词后,在括号中留下的名字,邮箱地址以及其他身份标志比如工号之类。修复后的代码应该不会再涉及废弃接口, 需要将该注释移除。 5.6代码规约下面我们大致讲下编码过程中的一些约定习惯。 5.6.1符号使用if/else/for/do/while语句,即使方法体是空的或只包含一个声明,开括号之前没有换行,开括号后换行,右括号前的换行符。仅在大括号终止一条语句或终止方法,构造函数构造方法或命名类的主体时,才在右括号后换行。 5.6.2缩进每次打开新的块或类似块的构造时,缩进量都会增加两个空格。当块结束时,缩进将返回到先前的缩进级别。缩进级别适用于整个块中的代码和注释。正确的缩进对于提高代码的可读性非常重要。为了使代码可读,程序员应适当使用空格。下面给出了一些间距约定:
5.6.3空格单个空白行也可能出现在它提高可读性的任何地方,例如在将代码组织为逻辑小节的语句之间。不鼓励在类的第一个成员或初始化程序之前,或在最后一个成员或初始化程序之后的空白行。 5.6.4列数Java代码的列数限制为100个字符。“字符”表示任何Unicode代码点。除非另有说明,否则超出此限制的任何行都必须进行换行, 5.7工具应用5.7.1命名工具https://unbug./codelf/ 5.7.2扫描工具首推阿里巴巴代码规约扫描工具,具体参考官方文档https://github.com/alibaba/p3c/tree/master/idea-plugin 6.代码审查如果说代码管理硬件设施,编码规范是主动出击,那么代码审查则是软件质量的后一道防线。本节我们将从代码评审的定义、意义、方法、步骤、度量等方面来介绍。 6.1定义代码审查是指对计算机源代码系统化地审查,以编码人员直接相互评审的方式进行,其目的是在找出及修正在软件开发初期未发现的错误,评估代码质量,提升软件质量及开发者的技术,通常代码审查过程包括以下阶段:
6.2意义软件代码审查在软件质量中起着重要作用,代码审查可以由多个人在多个交付品的多个阶段进行。人员之间可以专注于特定的软件领域,也可以交叉审查提升自身编码能力。代码审查首先可以降低风险,因为即使是优秀的开发人员也会错过某些东西,因此多一层代码审查始终可以提升质量,也就是时间换质量。此外,在共同检查代码时,每个团队成员都可以提出更明智的解决方案,以提高项目的总体性能和代码质量。 6.2.1优势团队代码审查有很多优点,整个团队的知识交叉学习,这将有助于及时沉淀知识库。同时关于代码可以发挥出多种观点看法,这将有助于提高代码和设计质量。团队审核的另一个重要优势是,初级员工有机会听取技术主管,经理或者架构师的意见,对于他们来说,这是一个很好的学习机会,可以了解他们的高年级同学的期望或者想法。
6.2.2劣势当然,代码审查确实是一项耗时耗人力的工作,完全执行甚至占到项目开发的很大一部分时间,这对于紧急项目来说也是一项挑战。但这并不意味着我们可以忽略掉代码审查,相反这更加考验我们对项目的排期和对工具的使用还有流程的编排。后面会介绍到项目审查的核心步骤和提效的扫描工具。 6.3准则代码审查大方向必须遵守一些准则,下面列出一些需要注意的方向:
6.4流程讲完代码审查需要关注的点之后,我们讲继续学习正确进行代码审查的姿势。 6.4.1审查方式通常我们理解的代码审查就是一个程序员对另外一个程序员的代码进行阅读,进而探讨,得出改进建议或者缺陷修复清单。但是为了适应不同的团队和工作场景,我们先介绍几种不同的代码审查方式。
当然随着软件行业的迅速发展,通常我们也会结合以上多种方式进行代码审查。 6.4.2审查流程以下是代码审查中遵循的过程:
6.4.3审查步骤
7.代码集成好了,经历完代码管理,编码规范和代码审查三部曲后,基本我们已经把技术这座高楼的地基砂石捋了一遍,牢牢的把握如何管理代码的艺术。但是随着技术的日新月异发展,旧的开发流程也不断在变更,从传统的软件开发流程到敏捷开发,还有最近几年的DevOps,慢慢过渡到面向未来架构的GitOps。尽管生产力工具在不断的变革,但是关于代码的朴素哲学思想却是坚如磐石,那就是在高效和稳定中寻找平衡点。 |
|