代码改变世界

[转载]需求分析的使命和方法

2009-04-02 09:41  周国选  阅读(178)  评论(0编辑  收藏

好久没有更新博客了。说实话,负罪感挺强。今天脑子被某个问题卡住了,暂时懒得深究。想想,不如写点文章,当作自己的休憩和对各位殷殷期待的答谢。

需求分析是个老话题了。从混混沌沌到人人重视,一些情况已经有了明显的变化。然而中国软件项目的成功率,似乎并没有特别大的提升。关键在于:从思想上重视到实践中掌握,从夸夸其谈到得其要领,还有很大的距离。曾经给某大学软件学院的学生上过一堂课。课本身固然非常成功,但是从一个侧面,我也看到软件学院的学生们对来自实践的一手知识、实践细节、具体考量等的了解渴求。简单地照本宣科,对工程性的人员来说,没有任何价值。大家想知道的是:做什么?怎么做?如何去做?什么时候这样做?什么时候不这样做?如何又是如何?如何判断什么时候是某个“什么时候”?如此穷究下去,直到所有问题与个人的基本经验和尝试建立起由个人基本经验和尝试可以连接起来的清晰联系。

那么在需求分析的实战中,要注意什么呢?个人感觉,至少要注意这样几个方面:
1)对变化是拥抱还是拒绝?还是半推半就?
2)需求分析是否关注细节,关注哪些细节?
3)需求分析能保证项目的成功吗?

首先看看变化。这个世界目前处于迅速变化的时代。尤其是中国,从历史尺度的眼光来看,简直就是在爆炸。这种节奏是否可以长期维持,是可以好好打几个大大的问号的。但是,只要目前我们所在时空的时间箭头没有改变,人类“短期”的发展模式没有改变,这种“局部时间”的小“社会时空”继续在一个更大规模的涨落量上表现出单边的快速涨升还会维持一段时间。那么,作为这种局面下的系统和软件开发人员,如何面对变化,确实是一个值得思考的问题。实际上,关于这个问题的“正确答案”早就有了,但是正确答案要转变成正确实践,就不是那么容易和简单。时间的最大特点就是,有太多的指标和理论模型纠缠在一起,主要挑战就是判断和权衡。实践的成功一定来自判断和权衡的总体正确,而不是理论的孰优孰劣。

“对变化是拥抱还是拒绝?还是半推半就?”对于这个问题,我的回答是坚决地“半推半就”。变化有很多种,有因为不深入的了解今日以为这样明日发现其实是那样的“变化”(A);有因为歧义或者过分依赖术语/常用语而不深究引起直到当某个词汇被澄清才让你发现的“变化”(B);有因为外部环境发生变化,企业迅速跟进而引起的变化(C);还有因为领导换人,不管有理无理都要标新立异而引起的变化(D)。

需求分析过程要尽可能避免A、B两类问题。出现这两类问题的时候,原因看起来是双方面的,但一般来说主要责任在于需求分析人员。因为需求分析的一个基本原则就是不要迷信术语,要讲业务流程和业务数据展开到业务层面的最细节。需求分析人员必须时刻注意对方的眼睛,发现其中的茫然、不解和困惑,而不是简单地将对方的点头和“嗯哦”当作是赞同。需求分析人员必须对不同的细节重要性有清醒的认识:细节作为一个概念确实非常重要,但是每一个现实的细节(细节的实例)并不都是一样重要的。如果对细节的重要性不能产生准确的判断和清醒地认识,不管在你心目中,需求获取和分析居于如何重要的地位,要得到令人满意的需求获取和分析结果都是非常困难的。因为无论你怎么脸皮厚,用户也没有时间听你把所有话题展开到最细微处。因此,辨别细节重要性能力就具有格外重要的意义。工程就是如此:你永远是在有限的空间、有限的时间、有限的资源下通过权衡解决有限的问题。只有分得清轻重,你才能取得成功。

对于C类问题,我们能做的是:具备一定的预见性。这又是一个需要权衡的问题。预见性过大,成本上升很好,预见性太小,面对变化时,哪怕是一些合乎道理、合乎规律的变化,也会导致巨大的开发成本。这种成本我们当然可以也应当要求用户承担。但是如果用户可以得到更好的服务呢?如果有人可以提供更有预见性的产品呢?用户的产品选型、项目开发其实也是一项工程,用户也是在诸多因素、诸多条件下权衡。只有善用权衡,才可能成功。只有拥抱竞争,才可能进步。因此,我的观点是,C类问题成本应由用户承担,但是对于一些“明显”的变化趋势,需求分析人员应该有预见性。开发人员应该通过预留接口和参数化等方式,对可预见的变化予以抽象化,并将区别抽象化为模型的高度一致和参数的设置不同。广义的,接口可以被看作一种参数化的行为,是将接口的外在表现抽象为高度一致的模型,而将接口的实现区隔出去的一种努力。对于C类问题,如果对于一些明显可以预见的变化没有充分准备,从而导致开发成本的上升,主要责任在于需求分析人员。

D类问题比较特殊,但是在我们这个极具特色的国家,还是挺常见的。对待此类问题,除了做好人事信息的收集工作和“危机”处理工作之外,就只有常常祈祷了。当然如果拥有结构超好,在一定领域内具有很高可塑性的框架或平台是会有裨益的。但即便如此,又有哪个系统能够自由到象不同人的心中瞬间就能疯长的意识的草。

前面讲了很多。有些问题并没有展开,比如如何确定哪些细节是重要的细节,如何才能提前掌握业务可能发生的变化?问题的答案既可以是经验主义的,也可以是系统性的。对于我来说,二者兼而有之。经验是思想的根,思想是经验的脑。关于学、思、行的关系,孔夫子讲了很多,在这点上,我看孔夫子的说法至今仍是非常恰当而精到的。那么如何确定哪些细节是重要的细节,如何才能提前掌握业务可能发生的变化呢?答案是面向对象的思维方式。面向对象的思维方式,最大的特点就是把业务领域的事物和规律,而不是其它的什么,作为分析和设计系统的基础。一个人要做好需求分析工作,就必须强化训练自己用业务语言描述系统功能性要求和非功能性需求的能力,知道这种能力近乎成为本能。当然,业务语言和技术语言有时候并不是完全对立,二者有交集。这在描述一些业务流程和业务数据的细节时尤其明显。实际上很多词汇与其说是技术词汇,不如说细节描述词汇。比如我们描述系统交互过程(这是系统需求分析的重点)时需要对流程中涉及的数据和信息的组成进行明渠的定义和说明:“用户需要输入订购数量、交货地址信息,订购数量是一个文本,长度可能有所限制”。
需求分析是什么?需求分析就是确定目标系统的边界。因此,关于这个边界的细节,都是我们必须严肃回答的问题。系统边界什么?说白了,就是用户(广义的,不限于人)与系统的交互流程和交互细节包括其中交互数据和信息的内容结构,很多时候,因为大多数用户是人,其与系统的边界就是UI,因此除了动态交互的流程和交互数据之外,界面布局本身都成为系统边界很重要的一部分。这些要素之所以成为系统边界,就在于绝大多数时候,系统对于用户俩说其实基本上是一个黑盒。用户只能对黑盒总体的外观和黑盒作为总体的输入与输出的时空关系,以及此输入、输出与彼输入、输出之间的时空关系做出限定。这里需要明确的是:所谓交互就是一个操作,动作的两头分别在系统的边界内外。两头都在系统外部或者两头都在系统内部的动作细节,不属于交互。因此,往往也不属于需求分析的范畴。当然,对“用户”的理解绝不应限于人,而应将其看作UML定义的Actor:可能是用户、外部系统、时间因素中的一种。之所以这三大类事物被看作Actor,是因为这三者都独立于系统本身,构成了系统本身存在的时空(用户和外部系统定义了系统空间环境)。描述系统的边界本质上就是描述系统的外在时空特征——在时间和空间上表现出来总体黑盒特性。从UML的眼光看过去,交互细节,就是每一个外部Actor和系统之间的关系。如果我们知道了世界上有什么东西,并且了解了这些东西之间有什么关系我们也就了解了整个世界。当然,我们必须了解:关系也是一种东西,关系和关系之间也可能存在关系。从这个高度看过去,需求分析和系统设计的方法论就其本质是一样的:就是穷举特定问题/时空领域内的所有“东西”,并且穷举这些东西之间的特定(你所关注的)时空关系,而穷举这些关系的根本办法就是“顺藤摸瓜”。顺藤摸瓜的“藤”还是“关系”。当这种根本方法被参数化到具体的需求分析方法时,在这个领域内,“东西”就主要是前面所说的三大类Actor和系统本身,“关系”就主要是Actor与系统之间存在的各种使用/交互关系。因为在这些交互过程中涉及到大量业务层面的数据(也就是业务对象)。因此这些业务对象之间的关系,以及它们与系统交互之间的关系也成为在这个领域内“顺藤摸瓜”的重要部分,而“穷尽"的基本原则就是反复思考这样一些问题,直到不再发现新的业务数据(业务对象)、新的系统交互过程和系统用户:
1)用户A为什么使用系统?有哪几种情况(Use Case)?
2)用户A在每一种Use Case下其交互过程是什么样的?其过程有什么业务条件分支和子交互过程?其过程中涉及到哪些业务对象?
3)每一对业务对象之间存在什么关系?
4)每一种业务对象都由谁生成、修改、传递、删除、查询?这些操作中哪些书允许的,哪些是被禁止的?那些又是有条件的?这些条件是什么?这些是否会引入新的交互过程?
5)用户原始需求描述中,所有具体语句中的动词、名词是否都被转换成交互过程、Actor、业务对象和业务操作。
6)所有业务过程是否都被展开为业务数据(业务对象及其属性)的分支何在分支上的业务对象及其属性的基本操作(创建、更新、删除、查询)顺序集合??
7)所有业务数据是否都被展开(直接或间接)为基本数据?这些基本数据一般表现为常常带有业务格式限制的日期、时间、数量(整数与小数)、编号、文本、金额。


现在回答前面的问题:如何确定在需求分析中,哪些细节是重要的需要展开的细节?答案已经很清楚了:那些如果一个词汇,不管是动词还是名词还是胸容词,如果很明显是可以进一步展开前述更基本的数据组合和操作组合或者基于基本数据和基本操作的量化限定的,而这种展开,在未澄清之前,具有极大的不确定性和多种变化,甚至其内部还可能进一步涉及其他需要展开的非基本数据和非基本操作的。这种细节就是需要高度警惕的细节。至于其他一些细节,不单独涉及其它的业务操作和业务操作,在系统中,总是仅仅作为其业务对象母体的丛书部分出现,并不具备更多的意义的。这样的细节就是较为次要的细节,比如用户个人信息中的某些附加数据,只要在对系统的分析过程中,除了在该对象的查阅交互中之外,没有其它交互过程直接或者间接依赖于该数据,这些数据就是次要的,追加成本很低的细节。

至于需求的变化,正常的主要是前面提到的C类情况。这种业务变化总体而言,总是基本按照业务自身的纹理发生变化的:就像堆放的木材总是按照其对方的角度和方式发生位移和错动。业务中的有些因素具有较其它因素更高的硬度:业务数据的种类构成较业务流程更为坚固,业务数据中涉及其它业务数据的部分总是较业务数据中“孤立”元素更为坚固,核心业务流程(用户使用/选择密度、频率、收入、利润较高的)较其它业务流程更为坚固。在这些强度对比之下,业务流程常常根据业务数据以及一些规则的选取和具体参数取值而发生着变化。从这种角度看过去,真正采用OOA/OOD开发的系统对于业务自身的合理变化(C类),具有“天生”的适应潜力。但是潜力要转变成实际的能力,还需要在OOA/OOD的具体实施上狠下功夫。

时间不早了,我准备去睡觉了。最后回答以下文章开头提出的第三个问题:“需求分析能保证项目的成功吗”?我的回答是:需求分析可以保证项目有一个好的开始,但绝不能保证项目的成功。即使抛开项目的商业成功,就算需求分析加上软件工程也不能保证项目的成功。需求分析保证我们可以较清晰地了解问题以及其今后变化方向。软件工程保证了系统开发过程的稳定性、可重复性、可优化性以及成功潜力的最大化。同样重要的还有设计和团队精神。需求分析决定了我们清晰、完整、正确、无歧异地了解自己要解决的问题,设计则帮助我们选择正确的路并通过指出正确、聪明的做事方式降低我们的开发成本、扩展成本、维护成本、延展成本。事情是人做的。我们可以通过好的架构、好的过程将对不同角度的个别人或者人群的过分依赖。但是团队作为整体,其战斗力、精神面貌是重视项目成功的重要保证。