我只需要给接口增加一个字段而已。
-- By 某销售同事
为什么我写这个
我在一家规模很小的征信公司工作。我们的开发团队包括 QA、UI 在内只有6个人。在过去的一年半里面,我们的团队从2人发展到6人,开发了一个含 Web UI 和 RESTful API 的案件管理系统、一个反欺诈规则引擎、一个用来统一访问和管理各种数据源的 API Service、一个用于计数和计费的 accounting system、基于 Pentaho 的一套 BI 报表、以及一个完整的 log centralize system 来对日志做收集和可视化(用 ELK Stack)。对了,还有公司的官网。考虑到我们连一个产品经理都没有,而且经常要兼职做客服的事实,我觉得开发团队的效率已经挺高的了。
但是,我确信如果没有说出本文开头那句话的人的影响,我们的效率还可以更高。其实很多时候我能理解他们的疑问:为什么听起来简单的一个功能需要这么长的时间?对于这个问题,其实我想用另一个问题来回答:为什么作为销售/市场人员的你,觉得你能合理估算开发一个功能需要的时间?
为什么你会低估开发时间
人们往往低估了细微改动的影响。大多数人不会认为从头开发一个产品是很简单的,但很多时候,销售/市场/产品的同事,会提出一个基于现有产品“很容易实现”的功能需求,他们往往认为只是“给接口增加一个字段而已”。这样的请求我在最近的一年里遇到过不止一次,那么我就来好好罗列一下一个这样的功能可能带来的影响。
当“增加一个字段”的需求产生,下面的改动几乎是任何公司的业务平台都无法避免的。
- 修改数据库中对应的表结构 =>可能需要增加/修改索引(Dev/DBA)
- 由于增加字段,ORM 层对应的类在序列化时的结果会改变,可能会影响所有其他使用到这个类的服务。这些地方的代码也需要调整 (Dev)
- 修改 API 使新增字段得以体现(Dev)
- 根据新增的字段更新 GUI 上对应的表单 and/or 表格的排版设计,实现前端功能(UI、Dev)
- 修改产品手册以及 API 文档(Dev、QA)
- 编写单元测试(Dev/QA)
- 回归测试所有依赖该类的功能(QA)
- 部署新的代码,对生产环境的数据库做 migration(Dev/DBA)
上述的某些改动可能会非常麻烦。比如增加的字段如果存在默认值,需要在数据库 migration 后更新该表中全部的已有数据。视数据一致性的需求,该工作可能需要中断服务来跑单独的数据库任务。一旦需要中断服务,我们还得告知在生产系统中调用我们 API 的一两百家客户,避免影响他们的业务。
还有更麻烦的。在前一段我仅仅罗列了和具体业务无关的内容,仅仅是增加一个字段的输入、输出变化引起的各项改动,而实际上改动可能远不止这么一点点。当然,如果你要增加一个字段,一定是想用这个字段的内容做点什么,因此不可避免的还会有很多业务逻辑在上面。比如对该字段做 validation、业务流程根据该字段的值做不同的处理,等等。以我们的产品为例,新增字段还要在规则引擎中做规则,要单独设计属性的图标,要在关联分析图包含这一属性上的关联信息,等等。这一切都需要大量的时间,需要对现有功能做非常仔细的考量,才能保证功能上线后不出问题。
以上就是一个改动的代价。如果你是一位销售经理,在告诉开发团队你的某个大客户需要“增加一个字段的时候”,希望你三思而行,你的一句话消耗掉的开发资源可能远远超过你的想象。当开发经理把预估的 man hour 发给你的时候,千万不要惊讶。你对你的无知一无所知。
“开发团队的时间都用在哪儿了?”
一个开发团队需要大量的时间来进行看似并不产生 output 的工作,包括而不限于:
- 编写测试用例
- code refactor
- 交流,如内部技术分享,code review 等等
上述2,3两点都是为了写出“可维护”的代码,但是代码可维护并不代表前面的那些步骤可以省略。它只能让你更容易做一些改变,而不至于带来什么不可预知的问题。
为什么软件开发时间难以估算
我并不奇怪市场或销售人员不能估算项目需要的时间。事实上,我见过的很多人,包括非常资深的项目经理,都做不到这一点。当项目经理估算失败,就意味着加班加点,意味着996。他们没有仔细阅读过《人月神话》,这是一本关于软件工程的,至今仍不过时的陈年好书。下面我要说的很多是从《人月神话》里看来的,并且在我的经验中得到了证实。
软件开发是一种脑力劳动。这里面主要的时间会花在试图理解以及研究需求、架构、实现细节上。只有很少的时间是用来敲键盘的。在软件真正开发完之前,没有人能准确的理解全部的细节。一旦理解的全部的细节,代码也随之编写完毕。人们很难对于自己没有完全理解的事物的复杂度进行准确的估计。
In theory, there is no difference between theory and practice. But, in practice, there is.
-- From "Use Case Driven Object Modeling with UML"
另一个问题在于,实际开发过程中可能会出现各式各样的问题。库版本不兼容了,GFW 又发威了,开源代码出 bug 了,甚至你发现你用了很长时间的 IDE 升级后突然崩溃了。。现实中真是有无数的意外,而 deadline 不能看到这一点。我曾经看到某 PM 说他是这么估计开发时间的:
- 先按正常标准预估时间
- 乘以2
- 再加上3天
- 再乘以3
虽然是玩笑,但是能考虑到意外因素带来的时间损耗,确实是经验丰富的 PM 的表现(当然,现实中我并不敢这样报告预估时间)。
总结
虽然说了上述的一堆道理,但是我真正的目的只是想吐槽而已:为什么我们公司找不来一个产品经理,导致我们需要从销售、市场那里接这些开发需求呢?