需求的实践(5)
细节需求时期(上)
从这一篇开始,我们开始进入细节需求时期。和业务建模时期注重于软件概貌不同的是,细节需求时期讲究充分挖掘涉众的需求,并作为其它的活动的输入。细节需求时期和业务建模时期有着不同的做法,迭代、小版本发布的思想是非常重要的。
1、细节需求时期和业务建模时期是不同的。
前面的章节谈了很多业务建模的知识,可以看到整个过程基本上是串在一起的,严格按照软件生命周期模型来说是属于瀑布模型。这里就有问题了,我们在讨论瀑布模型的时候已经用了很多的篇幅来鞭笞它了,这里我们又用回了这个模型,这是不是有点…。这样做的一个很大的原因是业务建模有它的特性。在一些小的项目中,业务建模在软件生命周期中所占比例一般不大,多半是为了了解业务环境的,其中BPA的成分会多一些,BPR的部分通常很少。所以其中如果发生了一些失误的地方,可以在需求阶段弥补。如果是那些诸如ERP的项目,那么业务建模和BPR会有很重要的位置,这个时候,一般要根据具体的情况来制定战略,很难说是采用何种周期模型。而且业务建模一般需要的人手不多,也会安排在项目的早期。所以只要有审查,业务建模采用何种生命周期模型并不是特别重要的。不过这是对于那些特定的项目而言的,对于市场化的产品来说,应该有另外的过程,但这并不在我们的讨论范围内,以后有机会的话再和大家讨论。
再说需求,需求的生命周期绝对不能按照瀑布模型的来。对程序员来说,最痛恨的一件事情就是需求改变。所以呢,大家想出一种需求凝固的办法,在分析完了需求后,就把它固定起来,写成文档,让客户签字。以后再有需求的增加或改变的话,就拿出这张纸说,"看吧,当时的要求可没有这一项啊。"这种做法的恶果是显而易见的。不过,有些企业则会反驳说,"没有啊,我向来都是视客户为上帝,这种事情我是不会做的,我会让程序员增加这个功能。"可惜的是,这种纵容顾客,伤害程序员的做法更糟。还记得我在听管理学课程的时候的一句话:"员工是最重要的,客户次之。"这是很有道理的,如果你的员工不满意,那么员工直接服务的客户又怎会满意?所以无论是哪一种做法,都只能暂时解决问题,对未来造成的危害却更大。
需求改变的危害很大,可是不变的需求从来就没有存在过。如果说,过去的社会中,企业的需求能够在一段相对长的时间内保持不变。那么,在现在这个全球化趋势愈来愈明显的社会中,一个不会变化的企业就只有死路一条。
曾经是大陆霸主的恐龙为什么会灭亡,而当时弱小的哺乳动物却能够存活下来,最大的原因就是面对着瞬息万变的自然环境,恐龙没有办法改变自身来适应环境,而哺乳动物则可以。现在的社会也是一样的。如果你的软件企业所服务的客户一家家歇菜,那你的下场也就可想而知了。所以,很明显的,需求和变化几乎就是同义词。
2、迭代
一方面是要求不变,一方面是要求改变。在这种矛盾的环境下,如何才能达到一个平衡点呢。
在已往的软件开发过程中,多半都要求对未来作出预测。例如,需求要有前瞻性,设计要有可延展性。可是这种做法往往难以实现。现实中的变化何止千万种,你都能做到算无遗策吗?如果你说你在做计划书的时候,可以估算到9月11号可能会发生灾难,那我就没话可说了。
一个中型以上的项目往往都需要数十人的团队工作半年以上才可能完成。这时候的计划还要加进人这个最不确定的因素。这样,正确的估计简直就是比登天还难。有很多自称考虑周详的计划书,在进度安排时连假期都没有考虑在内。这种计划,定与不定又有什么差别呢?
我最早接触迭代这个词是从一个朋友那里。他对我说:"自然界中的物体从来就没有以直线形式存在的,螺旋状的物体才是符合规律的,例如DNA。"他这话虽然听起来很玄。但是却很适合放在需求过程中。直线条的需求过程显得干涩,孤立,易断。而有螺旋的(迭代的,增量的)需求过程不论从那一个切面去看,都能够形成比较稳定的形状。
其实这个道理是很简单的。在我还是个写程序的菜鸟的时候,为了不至于编译时出现一大堆的Error,于是就采用稳扎稳打的方法,写一小段程序除一次bug。而迭代也是这样,是把以前需要一年才能看到结果的过程分成多个小过程,每隔一小段时间就可以看到一定的改进。体现在需求上,以前要一口气做完的需求往往会划分为多个的阶段,每个阶段完成一些功能。这样做有什么好处呢?
- 人们对较长的未来比较难以估计,但是却可以大致估计出短时间内的未来。这就好比我说不出两年后我是什么样,可如果是两个星期,我就有把握得多。
- 把一个大目标分割为多个小目标,这样人们能够不断的看到一个个目标被实现,这比长时间的等待大目标的实现要好的多。
- 客户总是说,我想看看软件才能提出更多的需求。这符合人的本性,应该予以满足。
- 不断的改进有利与开发人员和客户的合作程度的提高。
- 迭代的过程可以一定程度上消除原来品保人员等开发人员,开发人员等品保人员的瓶颈现象。
3、需求迭代的特殊性
迭代式的需求开发并不是意味着需求开发平均分到各个迭代周期来进行。在理论上,应该是先做完需求分析(还有构架设计),再着手进行各阶段的开发工作。可是实际情况中,需求要保持不变可太难了。根据自身的经验,一个项目,在一开始往往可以完成的需求开发可以占全部需求开发任务的80%(估算的数字)。但是在随后的软件开发中浮现出来的需求(新增或改动)又会有20%。可是这20%的需求是极不稳定的,可能分布在项目中期,也可能分布在项目晚期,甚至可能会在项目在部署阶段才会呈现出来,这些都取决于团队的能力。这样的项目的风险其实是很高的,有些较晚才浮现出来的需求可能会花费大量的资源来实现,如果这需求又对软件架构有影响的话,那后果更是灾难性的。
在XP中,一个迭代周期会包括多张素材卡片(Story Card),一张素材卡片都代表了系统的一项功能(functionality),这些素材卡片由项目负责人和客户、领域专家按照一定的规则,共同从需求集中抽取,决定在本次迭代中实现。一次迭代经过计划、准备素材卡片、分析、编码实现、测试、构建等步骤,呈现在用户面前的将是一个可以运行(can work)的软件。用户可以清晰的看到软件的界面,软件的使用手册,软件的输出结果。一切都是一览无遗的,不需要任何的叙述性的语句来描述软件,因为用户会自己去感受。接下来,用户的反馈意见被收集,分析,处理,必要的需求改变被安排在随后的某个迭代周期中实现。
单独的迭代可能是线性的,但是从整体上来看,多个迭代周期形成了一个流水线般的生产方式:
迭代示例 |
迭代1 | 迭代2 | 迭代3 | 迭代4 |
准备迭代2 | 构建迭代1 | | 准备迭代3 | 构建迭代2 | 交付迭代1 | 准备迭代4 | 构建迭代3 | 交付迭代2 | 准备迭代5 | 构建迭代4 | 交付迭代3 |
所以呢,需求迭代的特殊性在于需求的出现并非是迭代的,但是需求的分析和实现则是迭代的。
4、迭代的代价
就和计算机中任何的算法都必须寻求空间和时间的平衡一样,迭代方法虽然有其优势,但是同样需要付出代价。
由于要不断的对软件进行调整,所以软件的架构(Architecture)需要比较稳定,经得起变动。这一点可能在过去比较难,现在的软件架构都相当成熟,都能胜任这种工作。例如J2EE就是一个非常出色的架构。除了架构,系统的框架(Framework)也是非常的重要,框架要足够"软",这个方面虽然没有现成的框架可以利用,但是业界有很多关于这方面的资料,例如设计模式、分析模式。这些都是告诉你一些经验之谈。都是可以参考和采用的。
多个的发布版本要求开发团队有控制版本的能力。多个的开发版本如果不加控制到最后必然如同洪水猛兽一般可怕,开发人员的时间都浪费在各个版本的统一上。关于版本控制,有很多的软件都能够完成这一工作。对于比较小的团队来说,简单的目录控制可能就足够了。
上面画出的迭代示意图虽然好看,要实现可没有那么简单,如果功力不足,画虎不成反似犬,原来安排的迭代计划没有严格执行,结果是更