本文引自我的个人博客http://johncai.github.io/thought/2014/05/17/does-your-company-value-top-committers/

在一次部门PM会议中,一位PM提出可以在每个月的update meeting中评选一些表现不错的员工,比如执行code review最好的、最准时上班的等等,是个很不错的想法。大家继续思考还有哪些奖项时,其中一位说:提交代码最多的人,怎么样?或者提交代码次数最多的人!

听上去是个不错的建议,在我们这个软件开发部门,写代码是我们最主要的工作,这个奖项无疑是对程序员很大的鼓励和肯定。但我心里立刻就反应过来,这是危险很可能错误的做法。为什么呢?

一个程序员,如果提及代码次数比别人多,无非两种可能:

  1. 他比别人写了更多的代码。
  2. 他比别人提交代码更加频繁。

应该奖励写更多代码的程序员吗?

, 我很容易地就回想起,有一次要做某功能的发布时,发现性能不行,我看了下代码,大概100行,执行过程需要查询数据库10次左右,有些查询很慢。然后我把它重构(严格说应该是重写)到10行代码,查询数据库2次,性能不再是问题,顺利发布。

什么是重构?什么是重写?当你说重构时,首先,你得有女朋友,不对,首先,你得有测试;其次,要不你改生产代码而不改测试代码,要不你改测试代码而不改生产代码。这才叫重构;否则就是重写。

好的程序员通过写更少(而不是更多)的代码,来完成一个功能。用代码完成一件事,固然很爽,但很多好的程序员都有这个体会:删除大段大段的代码时,更爽。

因为更少的代码意味着更高效,更可维护,更节约别人读代码的时间(别忘记你花1天写的代码,会有10天以上的时间被别人读。),更能适应业务需求的变化。因此好的程序员对自己写出的大量代码心怀不安,而为自己更少的代码感到傲娇

更好的程序员不仅着力于用更少的代码去实现软件功能,更着力于开发更少的软件功能来满足更多的业务需求。软件的feature不是越多越好,如果开发出来的东西没人用,没有解决客户的问题,或者没有给客户带来便利,没有满足他们的需求,那么这样的feature是没有用的。

软件feature是软件开发团队的output,满足了多少客户的需求,才是outcome。outcome无非就几种:要么给客户省钱了,要么给客户赚钱了,要么提高了对客户的service,让客户的日子更幸福了。

优秀的程序员以解决客户需求为目标,首先保证开发的软件功能是真正需要的,也就是保证做对的事情,其次用对的方式写代码,尽量降低代码量。他不再是码农,他心里总是有一张影响地图,想着他要做的是如何通过代码影响他人。至于什么代码行数,则多么无聊的计数。

Do the right things. ATDD是重要的手段之一。

Do the things right. TDD是重要的手段之一。

应该奖励提交代码更频繁的程序员吗?

看情况。毫无疑问,应该频繁地提交代码,或者,更严格地说,频繁地集成你的代码。这意味着要做持续集成,意味着,不要打特性分支。

集成

经常看到有些程序员,把两天写的一大坨的代码commit。他们做不到每1到2小时就commit一次代码,那么意味着

  1. 他没掌握分解任务这一必备技能。
  2. 他在这两天失去了用代码跟其他程序员交流的机会。

写代码是一种创造性的活动,程序员用思想交流,好的程序员把思想反应到代码中(talk is cheap, show me the code),时时用代码与他人交流。

另外一些程序员提交代码时,不先做集成,集成至少意味着编译通过+单元测试的通过,表示我们这次提交没有破坏之前的任何东西。任何的一次破坏,对于其他程序员来说,都需要花时间去看哪里不对了,尤其是那些用代码交流的程序员,他们经常从服务器pull最新代码,他们需要服务器上的代码一直都是对的,以免中断并打扰他们的工作。

集成!

很多使用git的团队,为每一个feature打一个feature branch出来,然后做了上面所有的实践,直到feature完成,才merge回开发的主线上。这样的团队还是没明白集成的意思。集成就是在主线上集成的意思,没有其它意思。没事就打个branch,那是开源、超大团队不得已而为之的做法。

不在主线上的代码是不存在的。

当然,其实还是应该没事就打个branch,但在本地打,打出来做一些实验性的东西,打出来以便目前工作未完成时可以随时切换到另一个工作中去,打出个新天地。随打随删。git的branch就是个指针,好好利用。

所以,应该奖励提交代码更频繁的程序员吗?应该,如果他在做持续集成,他几乎从不破坏代码库,他以修复失败的CI为第一要务,他让所有程序员的工作流动而不停滞,他以更少代码为荣。