上一篇文章 中,我提到了一些开发过程中非常容易被忽略和轻视的工作,比如代码整理, commit 整理,添加测试等。做好这些工作不仅仅需要专业的知识,还需要非常强的自律才可以很好的完成。相比于精妙的算法和高大上的模式,做这些事情的优先级在很多开发团队里面比较低,通常可能是没人做。因为做好了这些事情,可能你也很难升职加薪,并且软件质量的提升也不是那么的明显(相比于改掉一些严重的 bug 而言)。

但是我相信很多开发者其实都是认可做好这些事情的价值的,而且国外的开源项目也是非常重视这些工作的。为什么没有做,或者又为什么这些事情没做好,我觉得可能跟人的惰性有关,自律这个东西太难。或许你会不同意我的观点,觉得可能是 PM 不给你专门的时间去做这些事情,所以才导致“碗都没人洗”。其实这个观点是有失偏颇的,更深层次的原因我感觉是开发流程上的随意、不规范,开发人员意识上的淡薄、不关心,还有产品导向、市场导向和结果导向的大环境。

洗碗本身是个体力活,也是个精细活,如果常年累月重复这些事情,难免也会厌倦并且于自身成长不利。但是,这些又是必须要做的事情,如果我们能把些事情自动化,或者有一些工具可以辅助我们更方便地做这些事,那么这些事情就会变成每天的刷牙洗脸一样。

声明:虽然电动牙刷非常好用,但是不代表每个买了电动牙刷的人都会坚持早晚刷牙的习惯。

Linter 工具和代码格式化工具

这里我主要讲一下 Js 语言的开发过程中的代码整理工作的自动化。首先,因为 Js 是动态类型语言,有很多写法错误没法像编译型语言一样在运行之前被编译器检查出来。

这个时候,我们就需要 ESLint 这样的 linter 工具了。这个工具除了可以帮你检查出潜在的语法问题,还可以配置检查代码的圈复杂度等信息。

另外,像很多语言有自己的代码编写规范,里面会定义很多排版规则。其实我本人是更喜欢自动化的代码格式化工具来做这些事情。这样的话团队里面所有的人写出来的代码风格都是一致的,而且可以很方便地保持一致。

持续集成和持续部署

持续集成(CI)和持续部署(CD)是现代软件开发过程中非常重要的两个环节,持续集成可以在代码提交到版本库之前,做很多自动化的“洗碗操作”。比如自动跑测试,自动跑 ESLint 工具。也可以代码合并之后,自动跑代码格式化工具。而持续部署可以让测试和产品人员更快地体验到迭代后的产品,然后随时跟开发同学反馈,形成一个快速反馈的闭环,有点类似于很多编程语言里面的 REPL。

Git Commit

关于 Git Commit 的编写规范,ruanyifeng 老师有一篇文章非常不错,里面的很多规范都是非常有说头的,重点不在于这些规范到底有多好,而在于文章里面提及了很多工具,可以辅助程序员编写合格的 Commit 日志。

另外,像 Emacs 的 magit ,也是非常好用的 git 工具,在做 interactive rebase 的时候非常好用,感兴趣的同学可以参考这个视频(请自行准备梯子)

自动化测试

测试一定要自动化,并且要能够非常快速地运行并给出结果反馈。成熟的开发者社区都有自己的自动化测试框架,当你把测试用例都准备好以后,可以在每日构建之后自动跑这些测试用例,然后生成测试报告抄送给团队相关人员。

这里面有一点必须提一下:测试用例的编写必须非常简单,最好是有工具可以辅助生成。像 OO 代码大多臃肿,非常不利于测试,而函数式风格的代码就很好编写测试。

测试代码也需要 easy to write, easy to read and easy to change.

无处不在的工具化

以前 web 开发的时候,修改完代码需要手动刷新浏览器,现在 hot reload 都成为了主流。

js 的语法糖里面有 destructuring1 特性,而这个特性可以帮助我们优雅地实现模式 RORO2

Rust 的编译器保证对象所有权的语义模型,保证了内存的安全。

React 和 nodejs 的各种脚手架项目,方便初学者入门,减少了大量重复性工作。

Java 的代码生成工具、重构工具,都可以极大地解放生产力,让 OO 代码的结构调整变得更加容易,同时程序员在利用这些工具去完成工作的时候幸福感也会更高。

总结

最后,关于代码重复的问题,相信今后随着机器学习的发展,对于简单的重复函数和重复结构应该是可以检查出来的,直接在 Pull Request 阶段就可以检查并标记出来。对于业务代码里面的知识重复,目前我还想不到什么自动化的方法,不过可以通过方案 Review 和代码评审解决掉一些。

熟悉我的人都知道我是一个工具控,我喜欢折腾各种实用好玩的工具,我本人也是一名非常重度的 Emacs 用户,喜欢在 Emacs 里面做任何事情,然后把这些事情集成到我的工作流之中,帮助我更好地解决问题。