需求分析与开发时间评估
# 需求分析与开发时间评估

今天想谈一谈关于“需求分析”和“开发时间”这两个话题，工作这么些年还是头一次公然讨论这个话题，今天聊一下我对这两个话题的浅见。

## 需求分析

早些年在我刚开始工作时，我认为“需求分析”就是听一听产品经理提的需求，评估下开发可行性和难度，把实现不了的需求砍掉。

这么多年过去了，我发现这是最Low Level的需求分析。

原因在于当时的我完全不知道产品经理为什么要提出这个需求，我甚至压根没有关注过这个问题，当时的我只关注这个需求如何实现，难度如何。所以我很难理解产品经理，甚至经常站在技术的角度认为产品经理提出的这个需求好SB啊，他是智障吗？

但其实产品经理和工程师不应该是敌对关系，**应该是“搭档”**，现在我和我们的产品经理一直是搭档关系，我们的关系很融洽，因为我们的目标是一致的：让我们的产品，满足用户的需求。

但有时候产品经理提出的需求可能不是很正确，这个时候需要工程师进行辅助。这里面有很多原因：

1. 产品经理可能对技术的边界不是很了解，所以无法充分利用技术解决用户需求
2. 对用户原始需求的理解是很难传递的
3. 产品经理对用户需求的理解有误
4. 其他

我们先讨论第一点：**“产品经理可能对技术的边界不是很了解”**。

### 产品经理可能对技术的边界不是很了解

优秀的产品经理是需要有技术广度的，他**不一定要深入了解技术的原理，但一定要理解技术的边界**。某个技术能做什么，不能做什么，最近是不是又有新技术了，和我的产品有关系吗？

但通常大多数产品经理都比较缺乏技术广度，所以这个时候需要工程师去补位。

但工程师去补位有一个前提，那就是工程师真的理解产品经理，理解他在想什么。这就要谈到第二点：**对用户原始需求的理解很难传递**。

### 对用户原始需求的理解很难传递

很多时候，产品只是发了个产品文档过来，然后就拉着技术做“需求评审”，但其实这份需求文档，是产品经理对用户需求理解的二次加工。工程师在这份需求文档里是很难看清用户的原始需求的。

> 比如：用户需要一个消息提醒。产品经理可能是不知道有Web Push Notifications这项技术，也可能是对用户需求理解有误，总之最终提出来的需求是在网页的最顶部添加一个消息通知功能。

所以工程师应该主动去了解用户的原始需求是什么，当工程师能理解用户的原始需求是什么时，也就能理解产品经理为什么提这个需求了，就可以在这个时候成为产品经理的搭档，提醒他，有一项技术叫做Web Push Notifications，它的能力边界是什么。

一个好的需求，应该是技术深度参与，而不是产品经理单方面输出一个产品需求文档，因为产品经理有时候也会犯错，这就是我们要谈论的第三点：**产品经理对用户需求的理解有误**。

### 产品经理对用户需求的理解有误

有时候用户反馈需求，或者产品经理在推测用户想要什么的时候，往往得到的答案是不正确的。因为有时候用户自己也不知道他需要什么。有一句名言非常有名：你如果问用户想要什么，他的回答是“一匹更快的马”，而不是汽车。

所以工程师要理解用户的原始需求，并且有自己的看法，这样不光可以给产品经理提出建设性意见，并且还可以对**技术方案进行“预判”**，如何设计项目的架构？最重要的就是要对产品未来的发展方向进行“预判”，一方面要对未来的改动 **“做足准备”**，另一方面也要避免 **“过度设计”**。

### 小结

总之需求分析不是简单的听一听产品经理提的需求，评估下开发可行性和难度，把实现不了的需求砍掉。而是去理解用户的原始需求，和产品经理成为“搭档”，在产品经理因为缺乏技术广度或其他原因导致提出坏需求时，给出提醒并提供建设性意见。

所以你会发现我的标题叫做“需求分析”而不是“需求评审”，因为“需求评审”的潜台词是：我不知道用户需要什么，我只知道产品如果提出了SB需求我就给这个需求砍掉。

讨论完需求分析，接下来讨论下“开发时间评估”。

## 开发时间评估

工作这么些年，直到今天我依然无法“准确”评估开发时间。

我认为是我的问题，是我没有掌握某些评估开发时间的方法论，为此我找了组内的技术专家和我的Leader请教他们是如何评估开发时间的。技术专家告诉我，可以用自己估算出的时间，乘以一个系数。我的Leader告诉我，可以根据以往的经验，来评估某个需求需要开发多少个“工作日”。

> 比如评估了5个工作日，但实际开发可能需要一个10个工作日。因为每天不一定一整天都在开发，还会去开会和处理其他杂事。

我评估的不是自然日什么时间完成，而是这个需求要多少个“有效工作日”可以完成。

评估好了有效工作日数，就可以根据工作日看需求的类型，有些需求是绝对不允许延期的，比如618，双十一这种需求都是不可能延期的，对于不可以延期的需求，如果评估出的有效工作日已经超出Deadline，那么这时候需要让产品经理把这个需求需要完成的所有功能的“重要程度”列出来，优先开发最重要的功能。如果评估后发现连最重要的功能都无法在Deadline之前完成，那么解决方案有两种，一种是寻求更多的资源，另一种是这个需求就整个砍掉。

听完之后，我学到了很多知识，“除了预估开发时间，别的我都学会了”。无论是“用评估的时间乘以一个系数”还是“根据经验评估有效工作日”，都没有正面回答如何准确预估开发时间的问题。

后来我又看了一些书，得出了一个结论：**没有人可以准确估算出开发时间，准确估算开发时间是不可能的**。

> 即使是特别简单的需求，也是无法准确评估开发时间的，例如：我可以准确的评估出我用一个工作日可以封装一个JSONP，但我无法准确评估几个小时能完成。
> 
> 这不是抬杠，这是一个道理，我虽然不知道我几个小时能完成，但是我知道我一天可以完成，我虽然不知道几天可以完成，但我知道一个星期肯定可以完成。

既然结论是评估的时间根本不准，那就不评估了么？和产品经理说我不知道需要多久，开发完了我再找你？肯定不行，产品经理一定会要一个开发时间，必须得给一个，哪怕不准。

既然开发时间是无法准确评估的，而我们又必须给一个开发时间，那么我们要做的事就不再是如何评估开发时间了，而是变成了“风险管理”。

### 风险管理

风险管理最常用的方法叫：留点余地。

这种方法的思想是，我知道自己评估的工作日不准，那么为了应对各种意料之外的事发生，我需要安排一些额外的时间来以备不测。

可能遇到的风险：

1. 这个功能比我预期的要难，需要更多的开发时间
2. 团队成员有急事请了两天假
3. 其他

用自己评估的工作日乘以一个系数，就属于这种类型。有一篇文章《我在淘宝做前端的这三年——第二年》里也介绍了一种方法也属于这种类型：

* 需求非常明确而且经常这样做：评估的工作日*1.5
* 需求不清晰，有可能变，但代码和技术方案熟悉：评估的工作日*2
* 需求不清晰，代码和技术方案也不熟悉需要探索：评估的时间*2.5

越不确定的事，未知的东西越多，风险越高，所以需要留有更多的时间以备不测。

我一般会问产品经理一个问题，我会和他说：你想要保守点的时间还是正常点的时间？保守点的是我用系数乘后的结果，正常点的是我凭经验和感觉认为多久能完成。

然后我会和他说：正常的时间，不一定准，我不能保证这个时间一定会完成，我只能尽力去完成，但保守的时间一定会完成。

通常最终商量后的结果就是把时间定到保守的时间上，然后开发尽量提前完成，但是最晚也不会超过保守的时间。

如果连不准确的开发时间都评估不出来，上面的方案不就失效了，那怎么办？

还有一个非常简单粗暴的方法：可以把需求难度分为三个等级：简单、中等、困难。

* 简单需求：需要2~3个有效工作日
* 中等需求：需要2~3周
* 困难需求：需要2~3个月

对于简单和中等难度的需求，在需求有DeadLine并且评估后发现最重要的功能也无法在Deadline之前完成，那么可以靠“堆人”来换取时间，但只适用于简单和中等难度的需求。对于复杂的需求，人员的数量根本没用，唯一可以让开发时间提前两个月以上，并且技术方案和质量都有保障的方案是：需要一个该领域的专家。

### 小结

经过我自己的经验和我请教的各种专家来看，结论是：开发时间的评估完全靠感觉，感觉是不靠谱的，所以最重要的事是做风险管理。
