一、概述📖
对系统应该提供的服务和受到的约束描述就是系统需求的内容,而需求工程就是建立系统需求的过程
需求描述了我们要分析、设计、实现和使用的软件系统的关键功能和因素,包括性能、成本、规划和其他特征
需求是有层次的,高层需求关注需要完成什么,如何完成,但是其实在每个层级,对于系统的所有硬件和软件的需求都要被界定
需求这个术语在软件行业中使用的可能很不一致,在某些情况下,一个需求被视为对系统应该提供的服务或者对系统的约束的一个高层抽象描述,但是在另一些比较极端的情况下,它又被定义成对系统功能的详细系统定义、用数学化的方式进行形式化描述
这种不同来自于应用场景不同,但是产生的文档都是需求文档:
- 当公司要与一家机构签订一个软件开发项目合同,那公司这边就要尽量概要地定义对这个项目的要求,而且这样的描述中不应该限制解决方案,这个时候就需要一个文本形式的需求来方便多个承包商竞标,或者以不同的方式满足客户的机构需求
- 一旦签订了合同,承包商就要写出更详细的系统定义,要让用户能看懂并要在此基础上确认系统到底需要提供哪些服务
需求类型
因为需要想不同类型的读者传递系统的信息,所以不同层次的需求是有用的,我们需要写不同详细程度的需求,是的不同的读者可以通过不同的方式阅读这些需求
用户需求这个术语是用来描述高层的概要需求,而系统需求用来详细描述系统应该提供哪些服务,用户需求是十分概括的,而系统需求对即将实现的系统所应该提供的服务和功能给出了更加详尽的信息
- 用户需求:用自然语言加图的形式给出的、关于系统需要提供哪些服务以及系统操作受到哪些约束的声明
- 系统需求:详细给出系统将要提供哪些服务以及系统所受到的约束,系统需求文档有的时候也被称为功能描述,应该是精确的,它可能成为系统买方和软件开发者之间合同的重要内容
用户需求的读者有:客户方管理者、系统最终用户、客户方工程师、承包商方管理者、系统体系架构师【不关心系统的实现方式和技术细节】
系统需求的读者有:系统最终用户、客户方管理者、系统体系架构师、软件开发人员【关心系统将如何支持业务过程或者是参与了系统的具体实现】
系统需求
i. 功能需求
包括系统应该提供的服务、如何对特殊输入做出反应,以及系统在特定条件下的行为描述,在某些情况下,功能需求还可能需要明确系统不应该做什么
1. 功能需求描述描述系统所提供的功能或者是服务,它取决于开发的软件类型、软件潜在的用户以及机构在写需求的时候采用的一般方法
它是多方面的,可以是系统所应该提供的服务这样的一般性需求,也可以是反映本地的特色工作方式或者是机构已有系统的特殊需求
如:系统每天能够为每个诊所生成一份想在那天预约就诊的病人名单1⃣️
2.如果是用户需求,那么就要用可以被系统用户理解的一种抽象方法来描述功能需求;然而更具体的系统功能需求则需要详细描述系统功能、输入输出、异常等
3.书写格式:The [feature or function] shall [do something based on user inputs and provide corresponding outputs]
4.要求:完备 + 一致
- 完备:用户所需要的所有服务都应该给出描述,如1⃣️,要求给出名单,名单里面的表项有什么之类也要说明白
- 一致:需求描述前后不能矛盾
但在大型、复杂的系统中,要求需求不仅完备而且一致是很难做到的:
- 复杂系统的需求描述很容易出现错误和遗漏
- 在一个大型系统中有很多信息持有者,他们通常持有不同和不一致的需求
ii. 非功能需求
对系统提供的服务或者功能给出的约束,包括时间约束、开发过程的约束和所受到的标准的约束,非功能需求通常适用于整个系统而不是个别系统的功能或者服务
只要有可能,我们就要让非功能需求能够量化
非功能需求是指那些不直接关系到系统向用户提供的具体服务的一类需求,和系统的总体特性相关(e.g. 可靠性、响应时间和存储空间占用),也就是说,它们对于系统的实现定义了约束(e.g. I/O设备的能力、和其他系统的接口等)
非功能性系统需求(e.g. 性能、安全性、可用性)通常会从总体上规范或者约束系统的特性,它通常会比个别功能性需求更加关键,如果系统用户发现有哪个功能不满足需求,他们还是可以克服,但是如果一个非功能系统需求没有满足,那么有可能导致整个系统没有办法正常运作
识别哪个系统组件实现特别的功能性需求是容易的,但是很难把这些组件和非功能需求联系起来,因为这些需求的实现可能散布在整个系统中:
- 非功能需求会影响整个系统的体系结构而不是个别的组件
- 单个的非功能需求可能会产生数个相关的功能性需求
非功能需求可以分为:
- 产品需求:定义和约束软件的行为,包括性能需求(e.g. 系统执行速度多快 + 内存消耗需要多少),可靠性需求(e.g. 系统可以接受的出错率), 信息安全性需求和可用性需求
- 机构需求:机构中采用的过程标准、实现上的要求(e.g. 程序设计语言和设计方法)、对产品及其文档交付的需求
- 外部需求:上级部门的监管要求、法律的需求、公众的道德需求
iii.领域需求
是从系统的应用域得出的而不是从个别的系统用户那里得到的,它们可能本身就是新的功能需求,也可能是约束现有的功能需求,或者是特别的计算必须如何进行的规定
领域需求的问题在于:
- Understandability:软件工程师可能对系统所运行的域的特点没有了解
- Implicitness: 无法掌握是否领域需求被遗漏或者是和其他需求发生冲突
软件域分析是指识别、分析和详细说明某个特定应用领域的共同需求,特定应用领域的范围从航空电子设备到银行业,从多媒体游戏到医疗设备里面的嵌入式系统
二、需求工程过程
1. 分为5个阶段:
- 可行性研究(feasibility study):评估系统对业务是不是有用
- 需求导出(requirement elicitation):需求发现
- 需求分析(requirement analysis):需求分析 + 需求描述
- 需求有效性验证(requirement validation):检验需求是不是正确定义客户希望的系统
- 需求管理(requirement management):应对需求的变化
需求工程是一个活动相互交错的迭代过程,伴随着系统需求文档的导出,将这些活动组织在一个螺旋结构的迭代过程中,每次迭代需要的时间和人力依赖于总过程所处在的阶段以及要开发的软件类型
2. 目标 :生成系统需求文档
a) 可行性分析(feasibility study)
是一个很短的很专注的分析,应该在需求工程的早期进行,检查系统是不是对机构的总体目标有贡献、能否在已有技术下在时间要求和预算范围内实现、能否和其他在使用中的系统集成等
b) 需求导出和分析(requirement elicitation)
在这个活动中,软件开发人员要和客户一起调查应用领域,也就是系统应该提供什么样的服务、具有什么样的性能和硬件约束等等
这是一个很困难的过程,原因是:
- 项目信息持有者没有办法清晰表达出他们的需求或者提出一些不切实际的需求
- 信息持有者会使用他们从事的工作中的专用术语和专业知识描述需求,需求工程师不能理解
- 不同的信息持有者会有不同的需求,并且会以不同的方式表达这种需求
- 政治上的因素:管理者提出特别的需求
- 进行需求分析的经济和业务环境是动态的
1. 需求发现:
这是一个和系统信息持有者进行交流从而发现他们的需求的过程,来自信息持有者的领域需求和文档也是在这个阶段中发现的,这一个阶段的信息源有:已有文件 + 系统信息持有者 + 类似系统的相关描述
需求发现是一个对于准备建立的系统和正在使用的系统进行信息收集并从这些信息中提取用户需求和系统需求的过程
需求发现技术:
- 技术1
- 视点(viewpoint):视点是一种收集和组织需求的方式,这些需求可能来自一组具有相同认知的信息持有者,因为每一个视点包含一组系统需求,视点可能来自于最终用户,可能来自于管理者,能够帮助识别不同的能够提供需求信息的人
- 技术2
- 采访(interview):对信息持有者的正式和非正式的采访时绝大多数需求工程过程的组成部分,分为封闭式采访和开放式采访,采访者需要思想开放,对需求不会先入为主,并且很善于听取信息持有者的意见
- 技术3
- 深入实际(ethnography):软件系统不是孤立存在的,是在一个社会或者机构的环境中使用的,软件需求来自于这样的环境,受到这样的环境的制约,满足这些社会的和机构的需求对系统的成功是至关重要的
- 深入实际就是用来了解操作过程并帮助导出这些过程支持性质的需求的观察技术,可以和原型法结合使用,分析人员通过观察日常工作,记录参与者相关的实际任务,能够帮忙发现隐性的系统需求,这些需求反映了人们的实际工作方式,能够观察到社会和机构的因素对工作的影响
- 适用于两种类型的需求发现:1⃣️需求来自人们实际的工作方式而不是过程定义中所要求的方式2⃣️需求来自于合作和对别人活动的了解
- 技术4
- 脚本(scenario):通常人们容易把事物和现实生活中的例子相互联系,不容易把事物的一个抽象描述联系起来,如果把人怎么样和一个软件系统交互用一个脚本来描述的话,人们就很容易理解
- 当把细节加入一个概要需求描述中的时候,脚本(场景)可能会很有用,脚本就是对交互实例片段的描述,每个脚本可能包含一个或多个可能的交互
- 绝大多数情况下脚本包括:
- 1⃣️在开始部分有一个系统和用户期望的描述
- 2⃣️一个关于标准事件流的描述
- 3⃣️一个关于可能出错的位置以及如何处理错误信息的描述
- 4⃣️有关其他可能同时进行的活动的信息
- 5⃣️在脚本完成之后系统状态的描述
- 技术5
- 用例(use case): 是一种需求发现技术,它是从参与者也就是最终用户的角度描述软件或者是系统的,用例识别一个单个交互,这是系统与用户之间或者不同的系统之间的交互
2. 需求分类和组织:
将无序的需求收集起来,重新组织整理,分成几个相关的组
3.需求优先权排序和协商:
在有多个项目相关人员参与的时候,很难避免需求之间的冲突,所以这个活动就是对需求优先权进行排序并通过协商发现并解决这些冲突
4.需求描述:
记录需求并将其作为螺旋下一循环的输出,产生形式化和非形式化的需求文档
软件需求文档(SRS):
SRS是对系统开发者需要实现什么的正式描述,应该包括系统的用户需求和一个详细的系统需求描述,它不是设计文档,与其说它关注怎样去实现,不如说它关注实现什么
用户需求需要让不具备专业技术方面知识的用户看懂
系统需求是用户需求的扩展版,是软件系统工程师的设计起点,它添加了很多细节,来说明如何能让系统提供用户需求,是对系统的一个详尽而完备的描述,它可以作为有关系统实现合同的一部分
SRS定义了系统的外部行为,描述了对于软件系统的约束,方便进行变更而且可以作为软件为何的参考工具【必须声明和功能(functionality)、性能(performance)、设计约束(design constraints)和外部接口(external interfaces)相关的功能】
需求文档中内容的详细程度取决于所要开发的系统的类型和所使用的开发过程,就比如说,在演化开发中,因为需求时刻在变化,所以可以不那么详细,在瀑布模型中,因为需求需要在设计阶段完备,所以需要很详细, 而当系统是由某个外部机构承担的时候,要求极高的一类的系统(critical system)的需求文档就要很详细
- 作用
- 帮助用户理解需求
- 提供一个验证最终产品的参考
- 高质量的SRS是保证软件高质量的基本条件
- 高质量的SRS能够降低开发成本
- 特征
- 清晰性(Unambiguous)
- 完整性(complete)
- 一致性(Consistent)
- 可验证性(Verifiable)
- 按照重要性或者稳定性排序(Ranked for importence and/or stability)
自然语言描述的SRS:
自然语言易于表达,直观且被普遍使用
但是问题在于:
- 描述不清晰(lack of clarity)
- 对需求理解错误(requirement confusions):阅读人员可能会误解功能需求和非功能需求,一个需求可能具有二义性
- 多个需求混在一个句子里面(requirement amalgamation),会给测试阶段带来麻烦
于是我们有结构化描述(structured description)
需求的作者的自由受到一定程度的限制,所有的需求都要通过一种方式来书写,但是好处在于它保持了自然语言中的绝大部分好的性质(表达能力和易懂性),但是对描述增加了一致性的约束,当用一个标准格式书写功能需求的时候要包括:
1⃣️所定义的功能或者实体的描述
2⃣️关于输入和输入来源的描述
3⃣️关于输出和输出去向的描述
4⃣️关于计算所需要的信息以及系统中所使用的其他实体的信息(“必需”)
5⃣️关于所采取的行动的描述
6⃣️如果使用了一个功能方法,前置条件设置为这个函数被调用之前必须为True的逻辑子句,后置条件设定为该功能执行之后为True的逻辑子句
7⃣️操作的副作用的描述
c) 需求有效性验证
检验需求是否真正按照客户的意愿来定义的系统的过程,它和需求分析有很多共性,都是要发现需求中的问题
需求的有效性验证很重要,如果在后续的开发或者系统投入使用的时候才发现需求文档出现了问题,那么就会导致更大代价的返工,由于需求问题对系统做出变更的成本远远高于修改设计或者代码错误的成本:需求的变更会造成设计和代码的变更,从而使得系统需要重新测试
需要进行多种类型的检查:
- 有效性检查(Validity)
- 一致性检查(Consistency) : 需求不出现冲突
- 完备性检查(Completeness):包括所用用户想要实现的功能或者约束
- 真实性检查(Realism):检查需求确保需求能够得到实现
- 可检验性检查(Verifiability) :能设计出一组检查方法来验证交付的系统满足每个定义的需求
有效性检验技术:
- 需求评审:当需求定义被公式化之后,应该进行经常性的正式或者非正式的评审,评审主要是为了检查可验证性(verifiability)、可读性(comprehensibility)、可追溯性(traceability)和可适应性(adaptability),客户和合同方都应该参与评审,软件开发者、客户和用户之间拥有好的交流和沟通使得在早期解决问题成为可能
- 原型建立
- 测试用例生成
d) 需求管理
需求管理就是在需求工程和系统开发过程中管理需求变化的过程
大型软件系统的需求总是在变化的,原因之一是通常要开发这些系统来满足棘手的问题,这些问题不可能被完全定义,所以软件需求注定是不完全的,同时,信息持有者对于问题的理解也是在不断变化的,因此系统需求也需要反映这些对问题观点的变化
我们需要跟踪各个需求和优先次序,维护有依赖关系的需求之间的联系来评估需求变更的影响,建立一个形式化的过程来形成变更建议并将他们和需求联系起来
变更的出现是不可避免的,原因如下:
- 业务、组织机构和技术上的变更会不可避免地导致需求的变更
- 系统业务和技术环境在安装之后总是在发生变化:可能引进新的硬件,业务优先次序可能会改变,立法和规章制度可能改变等等
- 系统购买者和系统的最终使用者很少是同一个人,系统客户可能因为机构或者预算约束对系统提出一些要求,而这些需求可能和最终用户需求冲突
- 大型系统通常拥有不同的用户群,不同的用户群有不同的需求和优先次序,很可能发生冲突和矛盾
需求变更管理应该应用于需求文档被确认之后对系统需求的所有变更提议,一共有3个基本阶段:
- 问题分析和变更描述: 开始于一个识别出来的需求问题或者是一份详尽的变更提议,在这个阶段要检验和分析变更提议的有效性,请求者要根据分析结果决定是要产生一个更详细的需求变更提议还是取消变更请求
- 变更分析和成本计算:变更的成本估算包括对于需求文档的修改,有的时候还包含系统设计和实现,一旦分析完成,就产生是否执行这个需求变更的决策
- 变更实现:必要的话,需求文档和系统设计和实现都要修改