无论是做产品,还是做项目,无可避免的要碰到代码过程管理的问题。这个问题主要是平衡产品质量,生产速度,开发投入的关系,并且设法增大乘积。

通常来说,质量,速度,投入三者是互相矛盾的,有的时候还要加上风险。质量越高,速度越快的生产过程,其投入也就越高。但是这几个关系并非单纯的并行替换关系,正如人月神话中所说的,人月这个单位暗示人和月是可以互换的,但实际不是。项目中主要碰到的问题往往是,在控制质量不变的情况下,增加投入不能提高速度。在控制速度不变的情况下,减小投入不能降低质量。偶尔,我们想方设法找到了一个方式,能够很好的满足质量-速度-投入的三元平衡,但是时灵时不灵,这就是风险元的问题了——通常情况下我们不会碰到。

作为平衡三者的起点,你不能从项目/产品的开始才考虑这个问题,而是必须从招聘/团队组建的时候开始考虑。一个不靠谱的人就会破坏整个团队,所以在招聘的时候,保持宁缺勿滥的思想。通常的项目/产品并不需要一堆天才,你只要一堆能够良好执行计划的员工就行了。靠谱的人的有几个要点,能够比较好的进行沟通,良好的计划制定和执行能力,大量的编码训练。有的时候我们往往以工作年限来衡量一个人的编码训练,实际上编码训练和工作年限并没有特别大的关系。好的项目经理/产品经理,应该能从编码的设计和实现中,嗅出编码训练的程度。

坚持只招聘合适的员工,事实上是以增大人力资源成本来解决速度-质量问题。因此通常只会被用于质量不变的情况下,增加投入提高速度。不幸的是,要实行这个步骤往往必须在项目的开始前进行计划。因此项目的正确做法不是添油战术,而是减油战术。减油战术的要点是强迫项目使用它天然能够使用的最多人手,使得项目处于人力资源相对充足的状况。再设法控制每个人的工作周期,不要让被分配的人做和他特质不吻合的工作。例如程序员完成编码后,不要让他去做文档/测试的工作,而是提前撤出项目。如果项目顺利,逐步撤出闲置人手组建其他项目,并保持项目依旧按时完成。如果项目仍旧不顺利,至少我们做到了我们能做的最快速度。

同时,这个战术涉及另外一个问题。我们都知道,越大的项目,需要的人手越多。而越多的人手,每增加一个人所能提高的效益就越低(俗称边际降低)。因此,平衡三者的另一个要点是切分项目,使其拥有完美的边界。假如一个系统,我们需要12个人工作半年。我们将其切分为两个相对独立的子系统,每个系统分配六个人,通常不用半年就可以完成项目。正常来说,项目所需资源随着复杂度增加往往是三次方到四次方增加的,而项目切分有助于使得前者随着后者线性增加。切分的优劣只取决于其边界的清晰程度和复杂程度,和需要多少人手,如何分配等等问题皆不相关。

在完成上述几个步骤后,我们就拥有了完美完成项目的一个起点,合适的成员,充足的人手,适当的边界。不幸的是,通常我们无法做到这么完美,成员不都是适当的,人手是不足的,需求是修改的,所以边界是模糊的。那么在整个代码过程中,我们依旧有一些可以做的事情。

首先是问题的早期发现,方法是代码规范,单元测试和交叉检查(cross check)。通常建议将人手编排成水平交错的一个环,按照顺时针方向,由一个人检查另一个人的代码。交叉检查有三重目的,帮助新手学习编码,抑制不小心和设计失当所造成的错误,当其中一个人无法工作时有人可以接手其工作。虽然这将付出一定时间,但是可以比较好的在前期发现和控制问题。同时,按照逆时针方向,编写另一个人的单元测试代码。单元测试有助于隔离问题范围,减少在实现中的一些无聊问题。

其次是问题的快速沟通和持续聚焦在工作上。强迫所有人每天写下需要处理的问题(todo list),然后每天勾掉解决的问题。这方法可以从各种GTD书籍上看到细节。同时,每天召开快速例行会议。将当天处理掉的todo list,碰到的问题和解决方法读出来。快速的沟通方便在早期把握员工的心不在焉,同时也方便其他员工发现潜在的可能与其相关的问题。

最后就是快速文档和后期文档相结合。在项目过程中提倡快速文档,即写下某个问题相关的精简描述和姓名,方便其他人联系你即可。在项目完成后,逐步补充文档,细化条目成为完整的文档。