个人软件过程3 需求分析
一间私募基金,希望开发软件实现他们自己的一种分析思路,这是一个小项目,我们隐去他们的分析思路,仅就行情更新和显示K线图这部分内容作为具体的例子,演示需求分析、阶段划分、任务划分、问题和Bug处理、源代码版本管理的全过程。这个项目由我个人承担全部工作,三个月的业余时间完成,本系列描述的是前两个月的工作内容。
我们首先需要确定项目的目标。简单的表述为:查看股票的K线图。这意味着我们需要每天更新当天的股市行情、除权除息资料,同时能够按照他们习惯的方式绘制K线图。
第二步则是列出功能清单: 所谓需求,是围绕着项目目标来定的。 既然要分析股票的走势,那么股票每天交易的行情数据,显然要保存,所以有“更新日线”,而除权除息,会影响到收盘价和成交量,为了让行情变化更精确,需要导入两个市场的权息资料。这些东西未必是用户能单方面写好交给你的。用户能够解释清楚他做这个项目的意图,你能够理解,最终用上面简单的文字表达,用户能够认可,这就是需求分析的过程。
我们也要注意一点,项目目标和功能清单是用户要看的,必须使用用户的语言,不要有任何计算机专业的术语。我们的思考是在"要做什么“的层次,而不是”怎么去做"的层次,所以这个过程中完全不需要做技术细节方面的考量。
同时,功能这个词,有许多别名:用例、用户故事、情景、用户场景等等,各自都号称自己有所不同。但我的看法是,你能够轻松的告诉用户,“我们已经完成了三项功能”,但你不能对用户这么说“我们完成了三项用户场景”,听起来真的挺二的。作为项目经理很多年,我在团队中强调最多的,不是那些不靠谱的勤奋、专心之类的东西,而是“要说人话,不要说鬼话”。再复杂的东西,有办法用大白话给多数人讲清楚,这就说明你自己是真明白了。
每项功能,请大家注意语法:动宾结构,大致是“做”“什么”。比如“更新”是动词,更新什么,更新日线。主谓宾大家是知道的,这里忽略了“谁”来做什么,这个主语。比如查看K线图,一些程序员很容易写成“生成K线图”,这里的区别是立场问题,查看是用户在查看,生成是机器在生成。功能的名称应该体现用户要做的事情,站在用户的角度思考,而不是机器或者程序员要做什么。
不要试图在需求中列出所有的业务细节,我的理解,需求更侧重于阐述用户目标,“他们希望干什么”,而不是“怎么干”,文字工作才不会太多。许多大公司动不动几百页的文字,我很怀疑用户和程序员是否有精力去看,那只是招投标的形式主义罢了。至于“怎么干”,在下一节我用“更新日线”这项功能具体来说明,如何用较少的文字清晰的说清楚“怎么干”。
功能清单的顺序和大小比较重要,我们按照先做什么后做什么这样的方式列出功能清单。那么顺序如何确定?一般的原则是"用户能尽快看到结果",其次的原则是"高风险优先"。比如正常的排列,我们应该先用模拟数据实现"显示K线图"功能,然后更新日线,然后处理复权。不过虑到对VC完全没有接触过,更新日线这项功能涉及到界面处理体系、文件操作、数据库操作、多线程编程等多个方面的内容,覆盖的知识范围更广,从学习VC编程的角度来说,更为合适。所以我按照更新日线、查看K线图、复权这样的顺序来排列。对于功能相对大小的评估,我们可以看到,复权应该是最简单的,定为2,更新日线大约需要2倍的时间,定为4。查看K线图也定为4,至于单位,有的体系叫做故事点、情景点或者理想工作时,无所谓,我们只需要一个大概的工作量评估。功能清单简单的罗列如下:
1、更新日线 4
2、查看K线图 4
3、复权 2
第三步,评估风险因素:
1、因为要做成桌面系统,基金成员各自的电脑操作系统不一,同时这个项目是海量计算的项目,所以最好的选择是使用VC开发。这个我从来没用过,需要在项目过程中边学边做。这也是很有意思的事情,多年前我的母校,武汉大学,计算机编程入门的课程是Pascal,老师当时还给大家解释Basic是如何不肖、用C语言入门如何不好,然后李卫华教授因为自己以人工智能为主要的研究领域,给我们开了Lisp和Prolog两门课程,出来工作后,主要用foxpro做过应用、然后是turbo Pascal,即使是汇编语言也玩弄得精熟(因为当时无聊的去分析汉化Dos的源代码),然后从.net平台推出开始,就一直停留下Asp.net和Wpf,整个职业经历居然与编程语言排行榜中的头两位无缘:java和C++。
2、时间和人员方面:因为公司技术人员忙于另外一个企业项目,出于对证券行业的兴趣,接下这个项目。我本人大约每天能够有3到5个小时的时间、周六周日的部分时间。
简单的说:用从来没有用过的语言,在从未接触过的领域,花费三个月的业余时间,完成具有相当算法复杂性的项目。
当然最后的结果肯定是皆大欢喜的,否则我不会拿出来显摆。这也说明兴趣和自信对工作效率的影响,你喜欢做的事情,必然会全力投入。至于VC,传说中复杂的C++语法、需要多少年才能精通的MFC,在我看来也就是窗户纸罢了-----对于类似MFC这类东西,我一向的原则是,你完全没必要学会制造电视、制造里面的每一块电路板,你只要会使用电视就行了,能有多复杂?至于语法,有C#的底子,反过来C++估计也不会困难。
风险因素是列给开发团队看的,对项目的时间安排是有意义的。当然,也是和用户在价格、时间方面讨价还价的依据。比如上述风险因素中,你没有用过VC是不能说的,否则用户很可能怀疑你能否胜任。自动划分趋势的复杂性可以强调,这样有助于在不能如期完成时,预先找到拖延的借口。所以风险因素罗列如下:
1、VC完全没有接触过
2、人员和时间不足。
第四步,划分阶段
我们按照功能清单的顺序、每项功能的相对大小、风险这三个方面的考虑,来划分阶段,每个阶段为四周的时间,要"彻底实现"罗列的功能,这也是Scrum、Rup之类过程同样注重的迭代开发、小版本发布的观念。简单的说:这个阶段完成的功能,通常就是用户最后见到的样子,伤其十指不如断其一指。之所以称作"阶段"而不是"迭代",这也是考虑到和用户交流方面的问题,仍然是那个原则:说人话。
那么第一个阶段,我们实现第一项功能;第二个阶段,我们实现第2、3两项功能。
对于工期紧张的项目,我一般以两周为一个阶段来安排时间。这个项目因为是业余时间工作,同时VC的学习有着不可预测的因素,因此按照每个阶段四周时间安排。
最后略微总结一下:通过和用户约两个小时的交流,我们知道了用户启动这个项目的目标,列出了功能清单,并用简单的文字描述,取得用户的认可。然后工作两个小时,列出风险因素、划分阶段。接下来我们将为第一个阶段第一项功能,划分开发任务、提出问题,这个过程大约也需要2小时左右。也就是说,对于这类小型项目,项目经理大约在一个工作日之内,就能够做好前期准备工作,第二天每个开发人员都能够在Team Fundation Server中看到自己的工作任务。即使是比较复杂的项目,这个过程也不用太长时间,我的极限是一周,任何情况下,从用户决定启动项目开始,最多一周之内开发团队的程序员就应该能够开始工作。
接下来的一节,我们将介绍第一项功能的概要说明、用户体验设计和任务划分。