沟通也是工程的一部分
极客与团队
市面上软件开发流程方面的书可以说是数不胜数。我们无意在此做过多深入的讨论,只想提几点和沟通特别有关的,无论遵循何种开发理念,这些要点都值得关注。
代码注释
代码注释风格是一样很主观的东西。原作者常常通过详细的注释解释自己的意图和理由,这些对理解代码都很有帮助,但是却要付出后续维护的代价:过时甚至不准确的注释反而会极大地妨碍对代码的理解。同样,过于扼要的注释,或者干脆没有注释也会浪费将来维护或者API用户的时间。注释一般是用来说明代码里缺失的部分,以及起得不好的名字,然后把代码的功能再解释一遍。注释应该尽量解释为什么代码要那么写,而不是去解释代码做了什么。
注释在函数(或者方法)层面是最有用的,特别是用作API文档的时候。注释不应该涉及过多细节,用一句著名的希腊谚语来总结就是“μηδέν άγαν”,即“过犹不及”。此外还应该好好为团队准备一套注释风格,然后每个人都要好好遵守——我们认为风格一致比风格本身更重要1。风格指南还应该自陈存在的理由及其目的——例如,这里是Google C++风格指南的介绍部分2。
C++是很多Google开源项目的主力开发语言。每个C++程序员都知道这门语言拥有多少强大特性,然而伴随这种强大特性的是它的复杂性,这也使得代码更容易出现bug,难以阅读和维护。
本文的目标是通过讲解C++编程中的各种要点来驾驭这种复杂度。这些规则在保证代码可控性的前提下,能让程序员高效地使用C++的语言特性。
所谓的风格(也就是可读性),就是管理C++代码的约定惯例。风格这个词本身有点不恰当,因为这些约定所涵盖的内容远远不止源文件格式化那么简单。
强制统一代码的风格是保持代码可控的一种方法。让别人快速看懂、理解代码是非常重要的。保持一致的风格并遵守约定意味着可以简单地通过“模式匹配”的方式来推断各种符号的含义以及它们具有哪些不变的特性等信息。通用和强制要求的习惯和模式可以帮助理解代码。有时候可能有很好的理由去改变某些风格,但是为了保证一致性,我们仍然会予以拒绝。
这份指南要解决的另一个问题是C++的特性膨胀。C++博大精深,拥有很多高级特性。有时候我们需要限制(甚至禁止)使用某些特性,这是为了保持代码简洁,避免这些特性带来的各种常见错误和问题。本指南会列出这些特性,并一一解释为什么要限制它们。
Google的开源项目都遵守这份指南的规定。
注意本指南并非C++教程,我们假定读者对这门语言已经有了相当的了解。
在源文件里署名(也就是“作者标签栏”问题)
每个人都希望自己的工作得到认可,艺术家会在自己的画作上签名,文字工作者会把自己的名字放在书脊上或是博客顶部。无论以何种方式,渴望得到认可是人的本性,但是在我们看来,在源文件里留下名字绝对是弊大于利。你一定在各种源文件的顶部见过这样的东西,它们往往和版权声明挤在一块儿。
# -------------------------------------------------
# Created: October 1998 by Brian W. Fitzpatrick <fitz@red-bean.com>
# -------------------------------------------------
在源代码顶部署名的传统已经是老黄历了(我们两个都这么干过,唉!),在程序大多由个人而非团队编写的年代这样做或许还说得过去。但是今天,很多人只是接触到一小块代码而已,文件里的作者标签栏只会导致争吵不休,浪费时间,甚至伤害感情。因此,我们强烈反对在源文件里署名的做法(最多也就是署上审核人的名字,告诉大家在修改这个文件后首先应该拿去给谁看,但是要小心不要有文件归属的暗示)。
想象一下,假如你在团队项目里新建了一个文件——编写了几百行代码,然后在文件顶部打上自己的名字和适当的版权信息,把它送去代码审查,然后提交给代码仓库。到目前为止一切正常。现在假设你的同事阿德里安跑过来修改了一下文件,那么他要改多少才有资格把自己的名字写上去呢?一定要修复一个bug以后?还是至少要五个bug?一定要实现一个函数?还是需要两个函数?要写多少行代码才够呢?如果他写了一个函数,然后在文件上加上自己的名字,结果这个函数又被后来的人重写了呢?这个人能不能也把她的名字加上去?是不是要把阿德里安的名字拿下来?和其他联合创作(比如剧作、小说、电影等)不同,软件即使在“完成”后依然会不断发生变化。因此电影可以在结尾放心地列出创作人员,可在源文件上这样添加、删除名字的做法却是一件永无止境的疯狂举动。
你当然可以通过大量文档来解决这些问题,但是维护、跟踪、防止意外发生都要浪费很多时间——这些时间原本都可以
用来写代码的。因此我们推荐在项目层面而不是代码上认可大家的工作。如果需要更多的细节,可以在版本控制系统里找到答案。一切都会随时间散去,就像雨中的泪滴3。
每个提交都必须经过代码审查
如果打算要实行某种编程标准,那么就必须要有监控哪些代码可以成为产品一部分的方法。无论是在提交之前还是之后进行代码审查,都应该保证每一行进入仓库的代码都要有作者之外的人检查过,检查的内容有风格、质量,当然还有粗心大意的错误。代码改动应该尽量短小以保证审查的质量——若改动涉及几千行代码,那么除了挑挑格式的毛病外,基本是没办法进行审查的。做到这一点不但能提高整个代码库的品质,更能从长远上培养代码质量的集体荣誉感。
真正的测试和发布流程
无论你是采用全套的测试驱动开发模式还是只有一些简单的回归测试,自动化程度越高,你在修复bug和添加新特性的时候就越自信。决定好测试所要扮演的角色后,它在编程和审查阶段都应该占有一席之地。发布流程也是一样重要,它应该方便到可以频繁发布的程度(比如每周一次),同时也要具备相当的完备性,这样才能在用户之前发现问题。