@Lenciel

The Importance of Deploy As Will

最近公司里面两个比较资深的开发兄弟在我座位旁边进行了一场关于“代码优化到什么程度才算好”的争论。

他们一起工作的项目是一个比较小的python模块(几百行的规模吧),用来在嵌入式设备对接入的手机进行一些操作。其中一个人希望把这部分代码重构到“如果需求有这样那样的改变能够承受。并且即便不是我们两个来继续这个模块,任何一个人拿到都能很容易的扩展和维护”;而另一个人则认为“这个模块的规模很小不需要那么大精力做重构,并且在需求出现的时候再开始在现有代码基础上重构比先设想可能的需求来重构有意义”。

他们争的时候都有眼神投射到小弟这边,但是我没有加入:因为其实两个人的说法都还挺有道理的,他们的分歧我感觉是因为背景不同:一个是在我大M出道的(慢工出细活的平台中间件公司),一个是在互联网公司出道的。

追求品质是成为优秀dev的不二法门

首先,作为一个dev,最优秀的品质大概就是一直想要优化自己的产出(扎克伯格的致员工信里面特别强调了这个很多次)。程序员的产出可以优化的东西是很多的:大到设计、算法、接口、自动化测试和部署,小到变量名、函数名、注释等等。自觉地重构和优化可以给你在技能和思考方式上带来很大的提升。而在自己入行的早期有幸遇到一个严格要求品质的mentor逼着被动的追求重构和优化,并且挺过来(挺过来很重要,要有学习能力并且有胸怀),更是能在工作方式和思考方式上得到很多非常正面的影响。我大M在我呆过的公司里面,这方面绝对是做得最好的。

什么时候够好要看你的deploy成本

但是,就这个项目而言,我个人是比较同意后面这位弟兄的看法的。软件项目可以做的重构和优化几乎是没有止境的,如何来衡量什么时候就“够好了”,业界其实有很多标准。但是我自己最喜欢的是Martin Fowler在一个演讲的时候提到的例子。他说:

假设你被要求设计一个电脑控制的手枪,要求在50米内自动瞄准并击中目标。需求只有这么一个。一种做法是设计一个复杂的系统,采集并计算各种可能的变量(风速、海拔、温度等等),以这些变量为基础瞄准并最后击发。还有一种是设计一个简单的系统,可以快速的击发,并且能够统计每一击距离目标多远。然后它根据收集回来的距离数据校正并迅速击中目标。

你可能会因为上下文觉得第二种方式当然是最好的,但其实上面两种方式是没有绝对的最优的:决定性的因素在于子弹的价钱。如果一个测量风速的模块都贵得可以买一车的子弹了,那么谁更好是显而易见的。

对于软件项目而言,Martin Fowler的例子中的目标就是你的用户,子弹的价钱就是你软件的deploy成本(当然,不要忘记了健全的用户反馈机制也很重要)。如果我们在造一个高可靠性的系统,比如发射火箭,显然是没法承受射出去一颗不行再来一颗的;如果我们在做一个小模块或者是小项目,那么一开始就很完美地设计并不断重构它,可能性价比确实不高。

对于Web开发者,理解Martin Fowler的例子显得特别重要。一般来说网站上线的初期(一年左右),是属于deploy成本比较低的时候。这时候在线的用户一般是抱着试玩的心态,对新功能的渴望远远超过对稳定性的要求,并且能够给出很多反馈意见。这个阶段迅速的deploy新功能,迅速的处理反馈并设计下一个新功能非常重要,而有一定时间的宕机或者回退用户并不那么在乎。所以那位互联网公司出道的兄弟有他那样的想法,也就不足为奇了。

到了用户量上去,或者重要的用户进场之后,deploy的成本就变得很高了。这个时候如果没有一整套严格的测试和运维流程,可能系统就玩不转。

结论

对于我司而言,目前和很长一段时间内的大多数产品都处于子弹不那么贵的阶段。个人感觉目前我们的CI和收集处理反馈这两方面是需要加强的,只有做到了"deploy as will",我们才有底气来以做互联网的方式来开发我们自己的产品。

而从长期来看,全面的提高项目品质,不仅需要dev自己有重构的自觉性,还需要我们有健全的融入到CI的测试以及成熟的运维团队。