对系统应提供的服务和所受到的约束的描述就是系统需求的内容。这些需求反映了客户对系统帮助其解决某些问题的需要,这些问题可以是:对设备的控制,安排一次订货,或者是信息的查询,等等。对服务和约束的发现、分析、建立文档、检验的过程叫做需求工程。
用户需求是用自然语言加图的形式给出的、关于系统需要提供哪些服务以及系统操作受到哪些约束的声明。
系统需求详细地给出系统将要提供的服务以及系统所受到的约束。系统需求文档有时也称为功能描述,应该是精确的。它可能成为系统买方和软件开发者之间合同的重要内容。
功能需求和非功能需求
软件系统需求常常分为功能需求和非功能需求:
- 功能需求:包括对系统应该提供的服务、如何对特殊输入做出反应,以及系统在特定条件下的行为的描述。在某些情况下,功能需求可能还需明确声明系统不应该做什么。
- 非功能需求:对系统提供的服务或功能给出的约束。包括时间约束、开发过程的约束和所受到的标准的约束。非功能需求经常适用于整个系统而不是个别的系统功能或服务。
功能需求
功能需求描述系统所提供的功能或服务。它取决于开发的软件类型、软件潜在的用户,以及机构在写需求时所采用的一般方法。如果是用户需求,就要用可以被系统用户理解的一种抽象方法来描述功能需求。然而更具体的功能性系统需求则需要详细地描述系统功能、输入和输出、异常等。
理论上,系统的功能需求描述应该既完备又一致。完备意味着用户所需的所有服务都应该给出描述。一致意味着需求描述不能前后矛盾。在实际中,对大型而又复杂的系统而言,要做到需求描述既完备又一致几乎是不可能的。一方面是因为在为复杂系统写需求描述时很容易出现错误和遗漏;另一方面是因为在一个大型系统中有很多信息持有者,一个信息持有者是在一定程度上被系统影响的一个人或一个角色。这些信息持有者经常有着不同和不一致的需求。在最初描述需求的时候,这些矛盾可能不明显,需求的不一致性就这样潜伏在描述中了。只有深入地分析之后或当系统交付客户使用之后问题才能暴露出来。
非功能需求
所谓非功能需求,如名字所示,是指那些不直接关系到系统向用户提供的具体服务的一类需求。它们与系统的总体特性相关,如可靠性、响应时间和储存空间占用等。换言之,它们对系统的实现定义了约束,如VO设备的能力、与其他系统接口的数据的表示等。
非功能性系统需求,例如性能,安全性,可用性,通常会从总体上规范或约束系统的特性。非功能性需求通常会比个别的功能性需求更加关键。系统用户经常发现所用系统并没有在某个功能方面满足他们的需求,但是还是能想办法克服这些不足。然而,如果一个非功能系统需求没有满足则可能使整个系统无法使用。举例来说,如果一个飞机系统不符合可靠性需求,它将不会被批准飞行;如果一个实时控制系统无法满足其性能需求,控制功能可能根本无法使用。
非功能需求的类型:
1、产品需求:这些需求定义或约束软件的行为。例子包括系统执行速度有多快和内存消耗需要多少等性能需求,包括指定系统可以接受的出错率等系统可靠性需求,也包括信息安全性需求和可用性需求。
2、机构需求:这些需求是很广泛的系统需求,起源于客户所在的机构和开发者所在的机构中的政策和规定。例子包括过程标准,即机构中采用的过程标准;实现要求,如所采用的程序设计语言和设计方法;交付需求,即有关对产品及其文档交付的要求。
3、外部需求:这也是个广泛的类别,包括所有来自于系统外部因素和开发过程的需求。这些需求会包括监管需求,指定什么是系统必须实现的以通过如中央银行这样的上级监管部门的批准;立法需求,必须得到遵守以确保系统在法律许可的范围内工作;道德需求,保证系统能被用户和一般社会公众所接受。
软件需求文档
软件需求文档(有时叫做软件需求描述或SRS)是对系统开发者需要实现什么的正式陈述。它应该包括系统的用户需求和一个详细的系统需求描述。在某些情况下,用户需求和系统需求被集中在一起描述。在其他的情况下,用户需求在系统需求的引言部分给出。如果有很多的需求,详细的系统需求可能被分隔到不同文档中单独描述。
需求文档的用户:
如下图为一个基于IEEE标准的需求文档的结构:
需求描述
需求描述就是在需求文档中写下用户需求和系统需求。在理想情况下,用户需求和系统需求应该具有清晰性、明确性、易读性、完整性和一致性。在实际中,这是很难做到的,因为信息持有者会用不同方式解释需求,而且在需求中常有内在的冲突和不一致性。
用户需求是从用户角度来描述系统功能需求和非功能需求,以便让不具备专业技术方面知识的用户能看懂。这样的需求描述只描述系统的外部行为,要尽量避免对系统设计特性的描述。因而,用户需求就不可能使用任何实现模型来描述,而是用自然语言、图形来叙述。
系统需求是用户需求的扩展版,是软件工程师开始系统设计的起点。系统需求添加了许多细节内容,解释如何能让系统提供用户需求。它们可以作为有关系统实现合同的一部分,因此它们是对系统的一个完备且详尽的描述。
系统需求描述的书写方法:
在使用自然语言书写需求时,为了尽力减少误解,推荐下面一些简单的指导准则:
- 设计一个标准格式,并保证所用的需求定义都遵循此格式书写。标准化格式不易发生遗漏,需求更易检查。使用的格式是用一个单个语句来表达需求。把需求原理和每一个用户需求联系起来解释提出需求的原因。需求原理里面可能也包括关于需求提出者的信息,这样在需要变更需求时就知道该找谁咨询。
- 使用一致性的语言来区分强制性需求和可选性需求。强制性需求是系统必须支持的,定义时要使用“必须”,可选性需求不是必要的,定义时要使用“应该”。
- 对文本加亮(粗体、斜体、颜色)来突出显示关键性需求。
- 不要认为读者会理解技术性软件工程语言。像体系结构、模块之类的语言很容易被误解。因此,要避免使用专业术语和缩写词。
- 在任何可能的情况下,都应该尝试把需求原理和每一个用户需求联系起来。需求原理应该解释需求产生的原因,在需求发生变更时它是尤其有用的,可以用来判断哪些改变是不可取的。
需求工程过程
需求工程过程包括有4个高层活动。它们是:评估系统是否对业务有用(系统可行性研究),需求发现(需求导出和分析),将需求转变为某种标准格式描述(需求描述),以及检验需求是否正确地定义了客户所希望的系统(需求有效性验证)。然而,在实际中需求工程是一个活动相互交错的迭代过程。
下图说明了这种交错性(需求工程过程的螺旋模型)。伴随着系统需求文档的导出,将这些活动组织在一个螺旋结构的迭代过程中。在一次迭代中每个活动所需要的时间和人力依赖于总过程所处在的阶段以及所要开发系统的类型。在过程初期,绝大多数人力都是用在对高层业务的理解、对非功能需求的理解以及对系统用户需求的理解。在过程的后期,在螺旋的外围,更多的人力将投人到需求导出和理解具体系统需求中。
螺旋模型所提供的开发方法准许我们将需求处理为不同详细程度。迭代的次数可以不同,这样螺旋就可以在经过若干或所有的用户需求导出后退出。敏捷开发模式可以代替原型开发模式,使得需求和系统实现一同进行。
需求导出和分析
在初始的可行性研究之后,下一个需求工程过程就是需求导出和分析。在这个活动中,软件开发技术人员要和客户及系统最终用户一起调查应用领域,即系统应该提供什么服务,系统应该具有什么样的性能以及硬件约束等。
需求导出和分析活动可能涉及机构中方方面面的人。系统信息持有者是指所有对系统需求有直接或间接影响力的人。包括将与系统交互的最终用户和机构中其他与系统有关的人员。其他的系统相关人员可能包括正在开发或维护其他相关系统的工程人员、业务主管、领域专家、工会代表等。
需求导出和分析过程的过程模型如下图。每个机构都会根据这个通用模型产生自己的版本,这依赖于内部因素,包括开发队伍的专业化水平、所开发系统的类型、采用的标准等。
过程活动包括:
- 需求发现:这是一个与系统的信息持有者交流从而发现他们的需求的过程。来自信息持有者的领域需求和文档也是在这个活动中得以发现的。在这一部分会讲到用于需求发现的一些补充技术。
- 需求分类和组织:该过程将无序的需求收集起来,对其重新组织和整理,将其分成相关的几个组。对需求归类有一个最常用方法,就是利用系统体系结构模型来识别子系统,并把需求与每一个子系统相关联。事实上,需求工程和体系结构设计不能是完全分离的活动。
- 需求优先权排序和协商:在有多个项目相关人员(信息持有者)参与的地方,需求将不可避免会发生冲突。这个活动就是对需求优先权排序并通过协商发现且解决这些冲突。
- 需求描述:记录需求并将它作为螺旋下一循环的输人,产生形式化的或非形式化的需求文档。
需求有效性验证
需求有效性验证是检验需求是否真正按客户的意愿来定义系统的过程。它和需求分析有很多共性,都是要发现需求中的问题。需求有效性验证很重要,如果在后续的开发或当系统投入使用时才发现需求文档中的错误,就会导致更大代价的返工。
由需求问题而对系统做出变更的成本比修改设计或代码错误的成本要大得多。理由是,需求的变更总是带来系统设计和实现的变更,从而使系统必须重新测试。
在需求有效性验证过程中,要对需求文档中定义的需求执行多种类型的检查。这些检查包括:
- 有效性检查:某个用户可能认为系统应该执行某项功能。然而,进一步的思考和分析可能发现还需要添加额外的功能,或是发现系统需要的是不同的功能。系统有很多不同的用户,而这些用户可能需要不同的功能,因此,任何一组需求都不可避免地要在不同用户之间协商。
- 一致性检查:在文档中,需求不应该彼此冲突。即对同一个系统功能不应出现不同的描述或相互矛盾的约束。
- 完备性检查:需求文档应该包括所有系统用户想要的功能和约束。
- 真实性检查:基于对已有技术的了解,检查需求以保证需求能真正实现。这些检查还要考虑到系统开发的预算和进度安排。
- 可检验性检查:为了减少在客户和开发商之间可能的争议,系统需求的书写应该总是使之是可以检验的。这意味着能设计出一组检查方法来验证交付的系统是否满足每一个定义的需求。
有许多能联合使用或单独使用的需求有效性验证技术,主要有:
- 需求评审:由一组评审人员对需求进行系统性分析,主要是错误检查和不一致性检查。
- 原型建立:在这个有效性验证方法中,为客户和最终用户提供一个可执行的系统模型。他们能在这个模型上体验从而检查系统是否符合他们的真正需要。
- 测试用例生成:需求应该是可测试的。如果将把对需求的测试作为有效性验证过程的一部分,经常会发现需求中很多问题。如果一个测试的设计很困难或是不可能的,那通常意味着需求的实现将会很困难,应该对此重新考虑。在编写任何代码之前就对用户需求开发测试用例是极限编程的一个完整部分。
需求管理
大型软件系统的需求总是在变化的。原因之一是通常要开发这些系统来满足棘手的问题,这些问题不可能被完全定义。因为问题没有被完全定义,所以软件需求注定是不完全的。在软件过程中,信息持有者对问题的理解是在不断变化的(如下图),因而系统需求必须要相应地反映这些对问题观点的改变。
一个系统一旦被安装并被正式使用,就会不可避免的产生新的需求。对于用户和系统客户来说,很难预料新系统将会对他们的业务过程和工作方法产生什么影响。一旦最终用户对系统有了经验,他们就会发现新的需求和更重要的需求。变更不可避免会出现的原因有以下几个:
- 系统业务和技术环境在安装之后总是在发生变化。新的硬件可能被引进,系统与其他系统的接口是必需的,业务优先次序可能会改变(并伴随着所要求的系统支持的变化),新的立法和规章制度的实行使得系统必须做相应的调整。
- 系统购买者和系统最终用户很少是同一人。系统客户可能因为机构原因或预算约柬对系统提出一些需求,而这些需求可能和最终用户需求冲突。而且在交付之后,如果系统要满足目标要求,就必须加入新的功能。
- 大型系统通常拥有不同的用户群。不同的用户有不同的需求和优先次序。这些可能是冲突的或是矛盾的。最终的系统需求不可避免要在他们之间进行折中,随着经验的积累,对不同用户支持上的这种平衡需要改变。
需求管理规划
规划是需求管理过程中第一个重要阶段。规划阶段要确定需求管理所需的细节水平。在需求管理阶段,必须决定以下内容:
- 需求识别:每个需求要有一个唯一的标识以便可以被其他需求交叉索引,同时可以用到可追溯的评估中。
- 变更管理过程:这是一组对变更带来的影响和成本进行评估的活动。这在紧接的一节中对此做更详细的讨论。
- 可追溯策略:这些策略定义了需求之间的关系以及需求和系统设计之间的关系,这些关系是要被记录下来的,对此要给出记录的维护方法。
- 工具支持:需求管理涉及对大量需求信息的加工。可以使用的工具的范围很广,从专家需求管理系统到电子表格和简单的数据库系统。
其中需要用工具支持的地方有:
- 需求存储:需求的存储应该是安全的、可管理的,在需求工程过程中的每个人对此都是可以访问的。
- 变更管理:变更管理(如下图)的过程若是由有效的工具来支持将变得很简单。
- 可追溯性管理:依照上面的讨论,对可追溯性的工具支持能发现相关的需求。一些使用自然语言处理技术的工具能发现需求之间可能的关联。
需求变更管理
一个变更管理过程有3个基本阶段:
- 问题分析和变更描述:该过程始于一个识别出来的需求问题或是一份详尽的变更提议。在这个阶段,要对问题或变更提议进行分析以检查它的有效性。分析结果反馈给变更请求者,请求者进而产生一个更加详尽的需求变更提议或是取消该变更请求。
- 变更分析和成本计算:使用可追溯性信息和系统需求的一般知识对被提议的变更所产生的影响进行评估。变更的成本估算包括对需求文档的修改,而且在适当的时候,还包括系统设计和实现。一旦分析完成,就有了对此需求变更是否执行的决策意见。
- 变更实现:必要的话,需求文档以及系统设计和实现都要做修改。要对需求文档进行组织,使得变更不会带来大量文字的重写和重组。与程序类似,文档的可追溯性是通过最小化外部引用和尽量使之模块化来实现的。这样,就可以修改和代替个别部分而不会影响文档的其他部分。