软件系统的目的是为了解决问题,因此在建模之初最重要的步骤是对问题的分析与定义,并在此基础上归结模型,这样才能够获得切实有效的模型。定义问题的过程包括:理解真实世界中的问题和用户的需要,并提出满足这些需要的解决方案的过程。
问题分析的目标就是在开发之前对要解决的问题有一个更透彻的理解。为了达到这一目标,通常需要经过在问题定义上达成共识,理解问题的本质,确定项目干系人和用户,定义系统的边界和确定系统实现的约束这五个步骤。
1.1 在问题定义上达成共识
要检验大家是否在问题的定义上达成了共识,最简单的方法就是把问题写出来,看看是否能够获得大家的认可。而要使得这个过程更加有效,应该将问题用标准化的格式写出来,根据 UP 的建议,应该包括以下几个方面的要素。
- 问题概述:用简短的几句话,将所理解的问题本质描述出来;
- 影响:说明该问题将会对哪些项目干系人(Stakeholder,风险承担者)产生影响;
- 结果:确定问题对项目干系人和商业活动会产生什么样的影响;
- 优点:概要性地提出解决方案,并列举出该解决方案的主要优点。
- 在问题定义上达成共识,就能够有效地将开发团队的理解与用户的需求达成一致,这样就能够使得整个系统的开发沿着合理的方向发展。
1.2 理解问题的本质
每一句描述都会夹杂着叙述者的个人理解和判断,因此透过表面深入本质,理解问题背后的问题,是问题分析阶段一个十分关键的任务。其中一种技术是 “ 根本原因 ” 分析,这是一种提示问题或其表象的根本原因的系统化方法。在实际的应用中,常使用因果鱼骨图和帕累托图两种方法。
(1)因果鱼骨图
因果鱼骨图是一种有效的探寻问题根源的技术,它通过直观的图形找出问题或现象的所有潜在原因,从而追踪出问题的根源。它能够帮助人们将问题的原因放在首位,提供了一种运用集体智慧解决问题的方法。在使用时,通常按照以下步骤进行。
- 将问题简明扼要地写在右边的方框里;
- 确定问题潜在原因的主要类别,将它们连到鱼的脊骨上;
- 用头脑风暴法寻找原因并归类。
图 1 是鱼骨图的一个示例。
(2)帕累托图
帕累托图是采用直方图的形式,根据问题的相对频率或大小从高往低降序排列,帮助设计师将精力集中在重要的问题上。它为 80% 的问题找到关键的 20% 的原因,它可以一目了然地显示出各个问题的相对重要程度,有助于预防在解决了一些问题后,却使另外一些问题变得更糟的现象发生。在使用时,通常按照以下步骤进行。
- 明确问题:也就是前面达成共识的问题定义;
- 找出问题的各种可能原因:通常可以利用头脑风暴来收集意见,并通过参考以往积累的资料和运营的数据来综合分析;
- 选择评价标准和考察期限:最常用的评价标准包括频率(占总原因的百分比)和费用(产生的影响),而考察的期限则应具有相应问题的代表性,并不是越长越好;
- 收集各种原因发生的频率及费用数据;
- 将原因按照发生的频率或费用从大到小排列起来;
- 将原因排在横轴上,频率或费用排列在纵轴上,形成如图 2 所示的结果。
这样就能够将造成问题的关键原因捕获出来,以便指导设计出更符合需要 、 更能够解决问题的解决方案。
1.3 确定项目干系人和用户
要想有效地解决问题,必须了解用户和其他相关的项目干系人(任何将从新系统或应用的实现中受到实质性影响的人)的需要。不同的项目干系人通常对问题有不同的看法和不同的需要,这些在解决问题时必须加以考虑。事实上,许多项目干系人就是系统的用户,这一部分通常是易于识别的;但还有一部分项目干系人是系统的间接用户,甚至只是受系统影响的商业结果,这一部分不易识别,但十分重要。
在寻找项目干系人时,可以思考:系统的用户是谁?系统的客户(购买者)是谁?还有哪些人会受到系统输出的影响?系统完成并投入使用后,有谁会对它进行评估?还有没有其他系统内部或外部的客户,他们的需要有没有必要去考虑?系统将来由谁来维护?
1.4 定义系统的边界
系统的边界是指解决方案系统和现实世界之间的边界。在系统边界中,信息以输入和输出的形式流入系统并由系统流向系统外的用户,所有和系统的交互都是通过系统和外界的接口进行的。在定义系统的边界时,将世界分为两个部分:系统及与系统进行交互的事物。要描述系统的边界有两种方法:一种是结构化分析中的 “ 上下文范围图 ” ,另一种则是面向对象分析中的 “ 用例模型 ” 。
(1)上下文范围图
也就是数据流图中的顶层图,它是一个反映领域信息的模型,能够清晰地显示出系统的工作职责和相邻系统的职责起止之处,从而让我们能够从宏观的层面去了解系统。图 3 就是一个描述 “ 证券经纪人系统 ” 的上下文范围图。
(2)用例模型
用例模型则通过引入参与者来描述 “ 和系统进行交互的事物 ” ,只要识别了参与者,自然而然系统的界限就确定下来了。在寻找参与者时,可以思考以下问题:谁会对系统提供信息?谁会在系统中使用信息?谁会从系统中删除信息?谁将操作系统?系统将会在哪里被使用?系统从哪里得到信息?哪些外部系统要和系统进行交互?
然后,再根据每个参与者的功能需求,识别出代表系统功能的用例,从而界定系统的边界。
1.5 确定系统实现的约束
由于各种因素的存在,会对解决方案的选择造成一定的限制,称这种限制为约束。每条约束都将影响到最后的解决方案的形成,甚至会影响是否能够提出解决方案。
在考虑约束时,首先应该考察到不同的约束源,其中包括进度 、 投资收益 、 人员 、 设备预算 、 环境 、 操作系统 、 数据库 、 主机和客户机系统 、 技术问题 、 行政问题 、 已有软件 、 公司总体战略和程序 、 工具和语言的选择 、 人员及其他资源限制等。
通过对问题进行细致周密的分析,就可以对其进行综合的定义。对于一个问题的完整定义,通常应包括目标 、 功能需求和非功能需求三个方面。
2.1 目标
目标是指构建系统的原因,它是最高层次的用户需求,是业务上的需要,而功能 、 性能需求则必须是以某种形式对该目标做出贡献。在描述目标时,应该注意以下几个方面。
- 优势:目标应该不仅仅是解决问题,还要提供业务上的优势;
- 度量:不仅要说明业务的优势,而且还必须提供度量这种优势的标准;
- 合理性:要确保完成解决方案所需的工作量少于所获得的业务优势,这才是合理的解决方案;
- 可行性:要探寻能够满足度量标准的解决方案;
- 可达成性:对于组织而言,是否具备获取该系统的技能,构建完成后是否能够操作它。
2.2 功能需求
功能需求是用来指明系统必须做的事情,只有这些行为的存在,才有系统存在的价值。功能需求应该源于业务需求,它只与问题域相关,与解决方案域无关。也就是说,功能需求是在与用户或某个业务人员交谈时,他们所描述的内容是为了完成他们某部分的工作而必须做的事情。
而在设计解决方案时,会遇到一些限制条件,这些东西也是 “ 系统需求 ” 的一部分,不过应该是设计约束或非功能需求形式指定。在规定功能需求时要注意其详细程度。由于这些需求是业务需求,因此应该由业务人员来验证。也就是说,用户应该能够指明系统要达到有用的程度,功能是否已经足够;考虑到工作的成果,它的功能是否正确。另外,在描述功能需求时,应该注意需求的二义性。而二义性主要体现在以下几个方面。
(1)同名异义的词:在自然语言中存在许多同名但异义的词语,应该谨慎地排除它们带来的影响。
(2)代词:在需求描述中,代词经常会产生指代不明的现象,应该尽量避免使用,而是换成主语及宾语。
在检查功能需求的二义性时,一种有效的方法是大声地朗读出来,大家一起边听边进行讨论,这样可以不断地优化。
2.3 非功能需求
非功能需求是系统必须具备的属性,这些属性可以看作是一些使产品具有吸引力 、 易用 、 快速或可靠的特征或属性。非功能需求并不改变产品的功能,它是为工作赋予特征的。
在识别功能需求和非功能需求时,有一种十分有用的思维模式:功能需求是以动词为特征的,而非功能性需求则是以副词为特征的。非功能需求主要包括以下几种。
(1)观感需求:即产品外观的精神实质,也就是与用户界面的观感相关的一组属性;
(2)易用性需求:也就是产品的易用性程度,以及特殊的可用性考虑,通常包括用户的接受率 、 因为引入该产品而提高的生产效率 、 错误率 、 特殊人群的可用性等指标;
(3)性能需求:也就是关于功能实现要求有多快 、 多可靠 、 多少处理量及多精确的约束。例如:速度 、 精度 、 安全性 、 容量 、 值范围 、 吞吐量 、 资源使用效率 、 可靠性(平均无故障时间) 、 可用性(不停机时间) 、 可扩展性等;
(4)可操作性需求:衡量产品的操作环境,以及对该操作环境必须考虑的问题;
(5)可维护性和可移植性需求:期望的改变,以及完成改变允许的时间;
(6)安全性需求:产品的安全保密性,通常体现为保密性 、 完整性和可获得性;
(7)文化和政策需求:由产品的开发者和使用者所带来的特别需求;
(8)法律需求:哪些法律和标准适用于本产品。