敏捷过程中有一个最重要的部分是需求拆分,需求拆分是个业界难题,在敏捷开发领域是如此。尽管每个敏捷流派对这个问题说起来都头头是道,但是要说谁有一个过目不忘的好方法,还真没有。
真正解决需求拆分问题的关键有两个:拆分后的颗粒度如何控制,拆分后的需求结构如何表达。前者可能问得比较多,因为多数程序员都要关心;后者只有产品经理会关心,所以显得不太突出,但对大产品和持续开发的产品而言则是个关键问题。
一、颗粒度问题
这个问题在敏捷框架下基本无解。
但在功能点分析(Function Point Analysis)中是一个基本概念。FPA通过对软件中的“业务数据”以及对其进行的“业务操作”为基本单元建立了颗粒度的概念,进而建立了规模的概念。这些概念的应用成熟度、推广程度、数据积累量(公开的在10000个左右,在咨询公司手中但非公开的在50000个左右,实际使用量不可估量)都远远超过敏捷开发或其他体系提出的方法,包括“故事点”。而且“业务操作”的概念非常接近用户故事,也包括如减少依赖、完整交付客户价值等描述。
下面举一个例子来看功能点到底是什么。这里将略去功能点中对数据、操作的复杂细节分析过程,而只说大概。
假设在一个OA系统中需要管理“用户”“角色”“权限”这三种业务数据,那么他们就是业务数据;而对他们分别进行的“增删改查”就是业务操作。比如“新建用户”“列出所有用户”都是业务操作。“业务”这个词在这里是相对于“技术”而言的,比如“新建用户”对客户而言是一个容易理解、认可的操作,而且客户管理员会告诉我们:
“是的,我现在每天都在新建用户,因为最近正在招人”而不会说“是的,我最近每天都在数据库表中新建记录,还会同步更新联系人数据表,因为最近正在招人”,虽然后者也的确发生了,但却不是客户日常工作的内容。
更神奇的是,“新建用户”这个操作,在无法获得更多细节的情况下,可以假设工作量为4人天(在OA系统中,其他系统有调整因子);而统计还表明,“用户”及所有与之相关的操作如刚才说的“新建用户”以及其他“删除用户”“列出所有用户”“编辑用户”……的总工作量(从需求到部署)大约是40人天,也就是2个人月,即使暂时不能确定到底有多少个操作。而“用户”“角色”“权限”及其所有操作完成的工作量自然就是大约6人月。尽管每个数据或操作的时间可能会有出入,但总体规模则误差不大。
这得益于大数定理及众多统计数据的分析结果。本段内容的详情可在Google查询“nesma”(一个总部在荷兰的世界第二大功能点组织),这个简化体系称为“Indicative Function Point”(指示性的功能点),在其网站上有荷兰语和英语介绍。
如果对用户故事的定义(而非“业务操作”的定义,因为后者更完善、严格)略作约束,则可以迅速与功能点中的“业务操作”兼容。兼容的结果有两个,首先是很容易把握颗粒度,其次是功能点与工作量的比例关系极佳,可以迅速推知工作量。
二、需求结构问题
在敏捷开发中有一个不完善的答案:Product Backlog 和 Sprint Backlog。前者是整个产品的待开发项,后者是当前迭代的待开发项,两者内部都按优先级进行排序。
这个答案对项目经理(可以模糊理解为Scrum Master)和开发人员足够用了,因为他们主要关心时间上的开发问题,也就是现在让我做什么,什么时候要的问题。但对产品经理(可以模糊理解为Product Owner)而言,时间是一个维度,空间则是另外一个维度。
所谓空间维度,就是系统-子系统-模块-大需求-小需求……之间的关系问题,这完全不是一个一维表格能解决的。由于敏捷开发主要是一线开发人员和项目经理发明并推动的,所以空间维度一直被忽略。但这是需求分解过程中一个绕不过去的问题,因为人们不可能面对一个一个一维表格回答这个问题:“我们所有的功能都包括在这里呢吗?哪部分还略显粗糙希望继续分解?这些大需求包含哪些小需求?”
在UML中的答案比较完善,“用户 - Use Case”(人-功能)很好地把一批相关的功能联系起来。虽然只是非常简单的表达,但比把几个毫无关联的故事按优先级排在一起,或把几个密切相关的故事相隔十万八千里放置还是进步不少。UML中的模块则是一个更宏观的需求“目录”。
FPA虽然没有需求关系表达,但如果把“业务数据 - 业务操作”作为一个树形结构,很类似把UML中的“实体 – Use Case”作为一个树,形成“数据-功能”的关系。不过,这个体系没有提供更宏观尺度上的需求结构问题。
由于功能点、UML中的模块用例等概念都是有严格、确定化的定义的,所以分解的过程井然有序,很少出现“这个还要继续分吗?”“这样分是不是颗粒度太粗糙”之类的问题。我们自己正在做的项目需求就是借用FPA的业务数据-业务操作作为主要分解关系,上面再加上我们自己定义的子系统-模块两个级别形成了一个“故事树”。这个故事树比我之前所做过及所见过的任何其他方法表达的需求结构更为清晰。因此敏捷开发应该吸取或者配合这些方法,至少是其中的一部分思想来完成需求分解。
很多时候我们会觉得引入较为严格的定义会“有限制太难做”,但其实更难做的是“无规则无限制”下自由发挥。