那些做了一半的项目

  • 业务变动、组织调整,工作重心变了,项目做了一半直接砍掉,或者无限期停工。这大概是最常见的一种情形。
  • 由于前期的调研、设计的严重问题,或是市场等变化过于剧烈,项目做不下去了,静悄悄地黄了。
  • 项目还做,但是转交给某个其它的团队,这是我这一次遇到的情形。项目还存在,只不过所属关系已经发生变更。

文档和隐性成本

无论哪一种,有一点是毫无疑问的,那就是资源投入的浪费,无论是软件还是硬件。即便不砍掉,暂停一段时间,再恢复的时候,要捡起曾经的项目,一样需要一定的成本。而项目要转交给其它团队,软件的交接成本也相当可观。其实这没有什么奇怪的,这是软件的本质所决定的。具体来说,软件开发,特别是上规模的软件开发,就意味着大量的 “隐性成本”。

从项目管理的角度来说,我们当然希望规范而且具体,或者说,大家都照章办事,项目设计可以纸面化,事无巨细地把 “为什么要这样做”,和 “‘这样做’ 是 ‘怎样做’ 的” 这样的信息都落地成文字交代清楚。可是你我程序员都知道,这是遗憾到不可能发生的事情。我在中国的大厂待过,也在北美的大厂待过,
有个别经历的团队和项目甚至被内部外部视作典范,可是客观地说,文档依然缺失,而且不是缺失一点,而是大量地缺失,再好的项目也是如此。

有一个有意思的网站,叫做 Killed by Google
,上面记录了被 Google 砍掉的项目。

其实,这并不是什么不可理喻的事情,相反,如果一个一定规模的软件项目,文档清清楚楚,把项目事项和设计细节都交代得清清楚楚,我反而觉得这个项目有着猫腻。因为
代码和文档永远有着显著而不可调和的矛盾

。为什么呢?因为对于软件工程师来说,一个且只有一个真正的、准确的数据来源( Single Source of Truth
),是值得推崇的最佳实践。这样的指导思想是根植于他们脑海中的,一个凡是对 Engineering Excellence 有着追求的程序员,一定会把它放在相当重要的位置。而在多数情况下,文档和代码就是两个数据来源,且无法被统一,但是你我都知道,真正工作的一定是代码,代码才是真正的 source of truth,文档只能成为不断过时的那一个。
我知道一定会有声音说,难道不能及时更新文档吗?比方说,代码逻辑修改了,修改的工程师也负责更新文档。没错,但这过于理想化了,而且,就好像软件的世界里一致性和可用性经常是难以调和的矛盾一样,文档的细致程度,和保持准确性的能力,也一样是难以调和的:文档越是细致,就约难以被及时更新,也就越容易成为过时的文档。文档的更新,不但涉及到工作量的问题,它本身也不符合很多工程师基于代码的思维习惯,因为它的读者有了变化,而且叙述的方式也有了变化;再者,真正在业务中直接生效的,也是代码,文档相应地,总是显得那么间接。

对于大多数工程师来说,特别是某些踏入职场时间并不长的工程师来说,文档的地位要更低一些。就好像 “talk is cheap, show me the code” 已经被不可思议地滥用一样,他们对于代码有着过度的狂热。这原本不是什么坏事,软件工程师总是要立足的代码的,可是,软件工程所谓工程,它一定是一个复杂的结合体,代码只能是其中一部分,有时甚至只是一小部分。随着时间和阅历的增加,越发觉得合适的文档在软件工程中的价值,比方说,就在几年前,关于文档我的一点思考记录在这里,现在其实也已经有了更新。
再回到隐性成本的话题上来。已经说了,在文档缺失或过时的情况下,程序员需要去理解需求,并阅读代码来理解前前后后整个故事,这里面的时间成本和试错成本可想而知,可退一步说,哪怕真的文档齐全,要把这些东西消化掉,也依然需要大量的时间。我们都说程序员是一个终生学习的职业,而每一个项目,就是一个可观测的学习的单元。

是勇气还是荒唐?

这样的决定很多时候并不容易做出。我经历过的多数情况,都来自自上而下的决策。有时候部门调整(reorg),结果一些项目的重要性就发生变更,直接砍掉了。而甚至有时候整个部门或团队都砍掉了,我在亚马逊的时候就经历了这么一回,一个原本负责商品在欧洲内各个国家之间方便流通的团队就这样直接砍掉了,当时作为团队里的一份子,我获得了几个 “下家” 团队的选项。也就是说,工程师重新回归资源池,重新分配归属团队。
但也经历过自下而上的,做过的某个内部应用,本来也是摸着石头过河,第一个版本做出交付了,却发现可用性还是比较差,具体说就是流程还是过于苛刻和冗长,而这个问题又不是一个比较容易解决的问题,很难把它继续推广开去,因此这个项目就烂在半途中了。虽说不能说项目砍掉了,但已经低优先级、无限期搁置了,也就和砍掉没有什么太大区别了。
多数时候,这样的损失并不只有纸面上能看到的 “浪费” 那么简单。除了上面所说的隐性成本,还有对团队士气的打击。但是,这里面有一个值得玩味的话题,当一个团队全身心地、毫无保留地投身奉献于一个项目的时候,这里的风险就很容易不可控了。有一位团队经理给下属画饼的时候说过,“你要把 xxx 项目当做你自己的孩子一样”,无疑这对于传递 ownership 的精神,是一个很形象的比喻,可是项目可能会黄,到时候该怎么收场呢?因此我觉得这不是一个特别职业的表达。
最后,回想起来,这种 “做了一半的项目” 还真是挺常见的。非常遗憾,可对于一个大型的组织来说,回头是岸,及时止损,通常可不是坏事。这样的决定无疑需要勇气,更糟的结果是继续这个项目,决策下的越晚损失越大。软件工程似乎就是这样一个无完美解的难题,处处充满了看似可以避免的弯路和糟糕实践,可是换个项目重来一遍的时候,还是一样有这样那样的问题。这有点像是人生,大道理我们都懂,可还是过不好这一生。