软件工程原则

本文是翻译,版权归原作者所有



我经常思考,对于我在开发的各种机器人而言,合适的软件方法论应该是什么样子。我的想法随着时间的推移而演化,我看到了它们的作用。由于我没有受过正式的软件工程培训,这些都是我曾经看到过、听到过、阅读过的通用原则,我深信不疑(我写到这里,已经是凌晨 2 点了)。

免责:大多数建议来自其它资源。请查看附加的链接以查看详情。

既然写代码是最基础的,我就从如何编写代码开始。然后我们进入软件工程基础,它需要让软件合理地运转。

通用编程规则

在编码时,如果没有基本规则供你遵循,你的代码注定要失败且不可依赖。其它工作都基于此。很多人开始编程,想使用疯狂的模板魔法,每个地方都继承其它某些地方,然而,你必须停下来,编写易于理解和测试的简单代码。

有帮助的链接

软件代码库

对于每个程序员和编程团队而言,拥有一个代码库是必须的。有很多可用的免费工具,因此没有理由不用它们。

有了软件代码库,你就用在各个点保存代码,你就能回滚都先前的工作版本。代码库还让你在每个文件记录修改了什么、被谁修改了的日志。这些工具是和团队分享代码的优秀方式——没有必要来来回回用邮件发送代码。你还能把文档放入代码库,这样它就一直是可用的。

有很多可选项,cvs、svn、mercurial、git、bitkeeper 等。挑一个!

最近我在用一种托管的代码库服务,名叫 github.com——我喜欢与这个网站上的 git 打包的所有工具。bitbucket.org 是另一个类似选择。

我通常喜欢在根目录下按照如下目录创建代码库:

除了以上目录,我通常把项目的主 make file 和 README 放在根目录。

链接

Bug/问题追踪

用一个中央数据库追踪 bug,对于开发没有 bug 的优秀代码是非常重要的。任何人发现了 bug,用这种方式来报告,就不会丢失。仅仅告诉开发人员或给他们发邮件是不够的。人们忘性大。理想情况下,你不想让开发人员关闭 bug;你想让某人报告 bug,开发人员修复它,然后发现该 bug 的那个人确认它被正确地修复了。

一个 bug 报告需要三个条件:

  1. 你期望发生什么

  2. 实际发生了什么

  3. 重现可观察到的行为(比如 bug)的步骤。尽量最小化需要重现错误的步骤数。包括你在用的代码版本。

链接

自动化测试

你的每个过程/函数都应该有一组测试(经常叫做“单元测试”)以验证它们的功能。这些测试确保函数能够应付各种输入极端和组合。理想情况下,你应该针对一个函数内的每种可能控制提供测试。

比如,如果你在测试函数“sum(number1, number2)”,可以有下列测试文件:

int main () {
  assert( 2 = sum(1,1));
  assert( 0 = sum(-1,1));
  assert( NULL = sum(1,NULL)); // or whatever you want it to be doing…
  assert( 0 = sum(0,0));
  assert( 1999998 = sum(999999,999999));
  assert( 5 = sum(4.2,1)); // assuming integers and that floats are rounded.

  RETURN (TRUE);
}

在这个例子中,断言将要在失败和终止的地方打印出错误信息。(这只是我的小例子,一定可以被扩展和改善。它还可以修改为在编译时失败,这样你就无需“运行”它了。)

自动化(每天)构建系统

拥有一台构建服务器,在有人提交代码、或最小化地、每个晚上时构建,对于识别引入系统的不经意的 bug 和自动化运行测试,是非常有价值的。

你对一个模块做了修改,经常引起另一个模块的失败。但是作为开发人员,我们聚焦于我们的模块,倾向于尽量不重新编译所有代码来确保我们没有破坏其它地方。早些发现你搞坏的地方,常常是更好的。

某些修改倾向于让其它模块破坏更多的模块。例如,修改一个使用广泛的头文件或消息定义文件,会引起其它问题。

它还让程序员仅把编译好的代码提交到代码库而不破坏代码。如果他们提交了有问题的代码,构建工具可以/应该发送邮件,通知人们这次构建失败了(以及这是谁的错误)。

你可以弄一个快速脚本来签出代码库、构建、分析输出和邮件发送结果;也可以找一个合适的构建系统,比如 Jenkins。通常地,使用其他人的产品更加可靠,也可以有效利用你的时间。

链接

代码审查

代码审查是艰难的,但是它们也是减少代码中 bug 数量的最好办法。传统的代码审核——会议室里一个人站起来和其他人讨论所有代码(这个人从没见过该代码)——不会起作用!让人们熟悉程序的运行或许是有好处的,但是这不是代码审查和找到问题的最好办法。

为了做代码审查,你应该让该程序员给 1-3 名其他软件工程师发送审查请求。这个审查请求应该包含代码总览、流程图和访问代码的说明。工程师的数量和他们的经验应该符合代码的关键程度。每个参与审查的人应该是:

  1. 审查代码(比较明显)——不要拘泥于形式,你要珍惜自己的时间。

  2. 整理一份关于代码的问题清单。

  3. 编写一些测试,确保他们通过了(它们可以被提交,常常运行在每日构建)。

在一次大型审查之前的代码审查时,审查者应该关注的地方有:

(上面的这个清单和优秀编程实践有些类似,你注意到了吗?)

做了上面步骤后,就可以组织一次大会,人们坐下来,通读和审查代码;虽然这不是严格必需的。

审查代码应该是艰难的。让你的程序员习惯阅读代码和审查代码,有助于加强他们自己的编码。设置一名专门的 QA 人员审查代码也是有用的。

链接

编译系统

你应该使用一种编译工具,而不用手动编译每个文件。很可能最常用的工具是 make。

每个 make 文件应该至少有如下指令:

我相信,你应该能用一个命令来编译、安装、测试或清理你的整个系统了。正常情况下,我将为每个进程生成一个 make 文件,然后创建一个主 make 文件,来调用所有单独的 make 文件。让一个单个 make 文件编译所有文件,有利于安装新系统,也使得配置每日构建更加容易。

总结

为了让你的软件更加可靠,你还有其它喜爱的工具吗?请在下面留言。


译文:软件工程原则 》| 腊八粥