- 写出优秀的需求
优秀需求的特点
需求陈述的特点
下面列出在理想状况下每一个业务需求、用户需求、功能性需求和非功能性需求应该具备的特点。
>>完整性
为了便于读者理解,每一个需求都必须包含所有的必要信息。
在开发人员准备开发的部分需求里,应该已经解决掉所有的待定项。
>>正确性
每个需求必须能够准确描述符合用户要求的性能,同时也要清楚描述它所具有的功能。须从需求来源检查需求的正确性。
为了评估用户需求的正确性,用户代表或其用户代表应该审查需求。
>>可行性
它必须可以在一定条件下实现。这些条件包括已知的能力、系统的限定、运行环境还有项目所限定的时间、预算和人力资源。
>>必要性
每个需求都应该描述出其必要性。这可以是符合项目干系人期望的业务价值的性能需要或者是产品在市场上的差异性,或者来自于外部标准、政策或法规要求的需要。
>>优先级排序
根据对达到预期目标的重要程度来对业务需求排序。
>>无岐义
自然语言容易产生两种类型的二义性。
可理解性与没有歧义有关系:读者必须明白每个需求说的是什么。
不可能消除需求里面所有的歧义,这是人类语言本质决定的。
>>可验证性
不完整的、不一致的、不可实现的或者有歧义的需求都是不可验证的。
需求集合的特点
各个独立需求都有完美表述是不够的。需求集合是为某一个特定发布的基线或者迭代而产生的。
>>完整性
不要漏掉任何需求或必要的信息。实际上,对于任何一个系统,都不可能记录下每一个需求。
任何包含TBD的SRS都是不完整的。
>>一致性
一致性是指需求不能和同类型的需求或者更高一层的业务、用户或者系统需求发生冲突。
>>可修改性
需求总是可以重写的,不过应该维护每个需求的相关修改记录,尤其是它们已经纳入基线管理以后。
为了有利于修改,要避免重复性的需求说明。
>>可追溯性
可追溯的需求应该能够回溯到它的来源,也可以向下追溯到延伸自它的需求、设计元素、实现它的代码还有用来验证它的测试。
需求编写指南
把术语“写需求”理解为“表达需求知识”。
写文档时下面两个目标最重要:
>任何阅读需求的人对需求的解读要一致。
>每一个读者的解读都与作者试图表达的意思一致。
系统或用户的角度
对于功能性需求,可以从系统运行或是用户使用的角度来写。
>系统角度描述需求的一个通用模板(Mavin etal.2009):
【可选的前置条件】【可选的前置事件】系统应该【期望的系统响应】
>从用户角度来写的功能性需求:
某个【用户类别或者角色名称】应该能够【对某个对象】【做某事】【限定条件,响应时间或者质量描述】
另一个表述是“系统可以让(允许、准许或能使)【某个特定用户类别的名称】【做某事】”,
写作风格
写需求不同于写小说或写其他形式的文学作品。
首先把要点写出来,要点是我们要表述的需要或功能,紧接着是支持它的细节(依据、缘由、优先级和需求的其他特点)。
>>清晰和简洁
写文档时,请以正确的语法、拼写和标点符号构成完整的句子。句子和段落尽量简短明了。
>>关键词“应该”
最好坚持只用一个关键词,比如“应该”。
>>主动语态
用主动语态可以清楚地表述谁是使动者。
需求中“和”“或者”“另外”或者“也”这些词表明可能存在多个需求合并表述的情况。
在一个需求中,要避免使用“和/或者”,它会使读者产生不同的解读。
细化程度
需求规范应该细化到包含的信息刚刚够用的程度,让开发人员和测试人员正确实现。
恰当的细化
为了厘清和充实更高一级的需求,需求分析的一个重要任务就是对它进行充分的分解和细化。
在下列情景中,应该包含更多细节(Wiegers2006)。
>需求是为外部客户写的。
>开发和测试工作要发外包。
>项目团队成员分散在不同的地区。
>基于需求进行系统测试。
>需要进行精确估计。
>需要有需求的可追溯性。
下列情景中,包含的细节可以少一些。
>需求是在内部为公司完成的。
>客户广泛参与。
>开发人员有相关领域的经验。
>有前例可循,就像被替换的首个应用那样。
>使用一整套解决方案
一致的粒度
对于一个相互有关联的需求集合,最好使用一致的粒度来写功能性需求。
如果预见到需要大量不相关的测试用例才能够验证需求,就说明可能有几个需求被合并在一起,应该分开。
表述技巧
尽量使用最有效的表述方式。除了自然语言表述外,我们通常还习惯使用列表、表格、可视化分析模型、图表、数学公式、图片、音频片段和视频片段。
避免岐义
需求质量是从用户的视角来衡量的,而不是作者的角度。
模棱两可的词
一致并按照词汇表中的定义使用术语。留心同义词和近义词。
要避免使用这样的词语:可能地、适当地、一般地、近似地、通常地、系统地和迅速地。
因为有歧义的语言会导致需求不可验证,所以我们要避免使用晦涩的主观性措辞。
在需求中应该避免使用的岐义性词语
岐义性词语 | 改进方法 |
可接受的,胜任的 | 定义出可接受的标准并指出系统如何对此进行判断 |
和/或者 | 为了不让读者猜,明确指出要表达的是“和”、“或者”还是“它们的任何一个组合” |
切实可行的情况下尽可能多 | 不要让开发人员来确定什么是切实可行的。用TBD来标识并设置一个明确日期 |
最少、最小量、不多于、不超过 | 明确设置可接受的最小值和最大值 |
最好的、极大的、最多的 | 说明期望的标准以及最低可接受的标准 |
在……之间,从×到Y | 明确定义是否包括两个边界值 |
依赖 | 描述依赖关系的性质。比如,是另一个系统为本系统提供输入值?在软件运行之前,还必须先安装另一个软件吗?还是我们的系统需要另外的系统来执行计算或者其他服务? |
有效的 | 定义系统使用资源、执行某一个操作或者用户让系统运行特定任务的效率标准 |
迅速的、快的、快速的 | 规定系统执行某个动作时最低可接受的时间 |
灵活的、通用的 | 描述系统必须能认哪些方式适应操作环境、平台或者业务需要的改变 |
也就是说 | 许多人搞不清楚“也就是说”(接下来列出所有的项目)和“例如”(只是几个例子)的意思。不要用拉丁字母的缩写,应该使用英语 |
有提升,更好、更快、更高级、质量更高 | 对特定功能领域或是质量方面更好、更快的改进点进行量化 |
包括、包括但不限于、等等、就像、比如 | 不只是给出例子,要列出所有可能的值或功能,也可以给读者一个参阅完整列表的引用。否则,对于整个列表要包含哪些项目或列表何时终止,不同的读者会有不同的解读 |
在大多数情况下,通常、常常、几乎总是 | 要明确给出不适用的状况或情景以及这些情况会导致的后果。描述用户或系统如何区别这些场景 |
匹配的、相等的、符合的、同样的 | 对于文本的匹配,要定义是不是大小写敏感的比较。或包含子字符串,或以该子字符串开头,或完全匹配。匹配成功的意思是指哪一个?对于数字类比较,要规定数字比较的精度 |
最大化、最小化、最优化 | 给出指定参数可接受的最大值和最小值 |
通常、理想情况下 | 识别出异常或者非理想情况并描述系统在这些情景下的行为 |
可选的 | 明确指出是开发人员的选择、系统选择还是用户选择 |
可能,应该 | 会还是不会? |
合理的、有必要时、恰当的地方、如果可能、适用于 | 解释谁来做出判断,是开发人员还是用户? |
强健的 | 定义系统如何处理异常以及对非预期的操作条件做出响应 |
无缝的、透明的、平滑的 | “无缝”或者“平滑”对用户意味着什么?将用户的期望翻译成具体、可观察到的产品特征 |
几个、一些、许多、很少、多个、大量的 | 说明具体有多少,或者提供一个有最大值和最小值限定的范围 |
不应该,不会 | 尽可能以肯定句式来写需求。用系统应该怎么做来表述 |
时下流行的 | 定义这个词对项目干系人的具体含义 |
充分的 | 给出具体表示充分的数值 |
支持……功能、让……具有……功能 | 为了“支持”某种能力,确认定义系统要执行的具体功能 |
用户友好的、简单的、容易的 | 描述将满足用户使用需要和使用期望的系统特征 |
>>A/B结构
很多需求规范说明都包含“A/B”形式的表述。它们由两个相联系(同义词或者反义词)的词语以反斜杠连在一起。这样的表述常常会产生歧义。
>>边界值
业务规则和需求中,数字范围的边界常常会出现歧义。
对否定句式的需求应该尝试着用肯定语态来描述,以便清楚描述出有约束的行为。
避免不完整性
对避免遗漏功能有帮助的方法是把关注点放在获取用户的任务上而不是系统功能上。
>>对称性
成对的操作往往会造成遗漏需求。
>>复杂逻辑
复杂逻辑的表达常常都有意不定义特定的组合条件。
>>遗漏异常处理
对于描述系统在正常状态下如何工作的需求,必要时也应该有一个相对的需求,描述异常情况下系统应该如何响应。
业务分析师在重写需求时,不要主动引入设计上的限制。
- 一图胜千言
需求视图包括功能性需求清单、图表、可视化分析模型,用户界面原型、接收测试,决策树、决策表,照片、视频还有数学表达式(Wiegers2006)。
多样化的思考过程会创造出不同的需求表达方式,将这些表达方式和多样化的符号表达方法进行比较分析,就会发现用单一视图很难找出的不一致、歧义、假设和遗漏的需求。
需求建模
分析模型应该增强而不是替换以自然语言写的需求规范说明。书面需求所提供的详细程度和准确性对开发人员和测试仍然大有好处。
>可视化需求模型包括:
>数据流图(DFD)
>流程图,比如泳道图
>状态转换图(STD)和状态表
>对话图
>决策表和决策树
>事件-响应表
>需求树
>用例图
>活动图
>实体关系图(ERD)
相比采用标准的符号表示,采用自己臆想出来的建模符号会带来更大误解风险。
从客户需求到分析模型
用户需求和分析模型组件之间的关联
词语类型 | 示例 | 分析模型的组件 |
名词 | 人员、组织机构、软件系统、 数据元素或者已经存在的对象 | 外部实体、数据库房或者数据流(数据流图,DFD) 参与者(用例图) 实体或者实体属性(实体关系图,ERD) 通道(泳道图) 带状态的对象(状态转换,STD) |
动词 | 行为、用户或者系统所做的事情 或者能够发生的事件 | 处理(数据流图,DFD) 处理步骤(泳道图) 用例(用例图) 关系(实体关系图,ERD) 转换(状态转换图,STD) 活动(活动图) 事件(事件响应表) |
条件 | 条件逻辑的陈述,如if/then | 判定条件(决策树、决策表或者活动图) 分支(泳道图或者活动图) |
选择正确的表达方式
很少有团队需要为整个系统创建一套完整的分析模型。建模时要关注的重点往往是系统中最复杂的部分、最具风险的部分、不确定的或是容易产生歧义的部分。
系统中涉及安全性的元素、涉及保护机制的元素、涉及关键任务的元素是建模时很好的选择对象,因为在这些部分一旦出现缺陷,会带来较为严重的影响。
选择最合适的表达技巧
所表达的信息 | 表达技巧 |
系统的外部接口 | 项目环境图和用例图能够识别与系统交互的外部对象。 |
环境图和数据流图在高度抽象的层面描述系统的输入和输出 | |
生态关系图能识别出系统可能交互的对象,也包含间接有联系的对象 | |
泳道图描述不同系统之间所发生的交互行为 | |
外部交互的细节可以输入/输出文件格式或者报表格式记录 | |
同时包含软件和硬件组件的产品常常都有一个包含数据属性定义的规范说明,其形式或许是一个应用编程接口或者硬件设备的输入/输出说明 | |
业务过程图 | 顶层的数据流图从高层抽象表述业务过程处理数据的方式 |
泳道图描述在业务处理流程中参与不同处理步骤的角色 | |
优化后的数据流图或者泳道图能够在恰当的细节层次上表达业务处理流程 | |
流程图和活动图同样也可以用于高层抽象和低层抽象的视图描述,只不过它们通常都是用来定义流程细节的 | |
数据定义和数据对象关系 | 实体-关系图表述数据对象(实体)之间的逻辑联系 |
类图表述对象类和类对象数据间的逻辑联系 | |
数据词典包含数据结构的详细定义以及各个数据条目 | |
复杂的数据对象要逐步分解成它所包含的数据元素 | |
系统和对象状态 | 状态转换图和状态表是高度抽象的视图,呈现了系统或者对象可能的状态以及在一定条件下发生的转换 |
件响应表来作为范围工具,用它来识别外部事件(帮助定义产品的范围边界),通过在一个事件响应表里详述系统对外部事件和系统状态每个组合的不同响应方式,还可以用它来描写单个的功能需求 | |
功能性需求提供用户和系统行为导致状态变化的详细信息 | |
复杂逻辑 | 决策树表述一组相联系的判定或条件下可能的输出结果 |
对于一系列判断或条件的组合,决策表能识别出结果为真和假时各自的功能需求 | |
用户接口 | 对话图从高层级提供建议的或是实际的用户接口视图。它描述各种不同显示元素以及元素之间可能的导航路径 |
展示-行为-响应(Display-action-response)图描述了每一屏显示的元素及其各自的行为需求 | |
详细的屏幕布局和高精度的原型描述了界面元素的外观 | |
数据域定义和用户界面控制描述进一步提供更多的细节 | |
用户任务描述 | 用户故事,场景和用例规范说明在不同详细程度上描述用户任务 |
泳道图(Swimlane diagrams)描述了业务过程与多个用户或者系统之间的内部交互 | |
流程图和活动图直观描述了用例对话流程和其他可选流程和异常的分支 | |
功能性需求详尽描述系统和用户如何交互以获得有价值的输出。 | |
测试用例提供另一个低抽象层次的视图,描述在特定的输入、系统状态和操作条件下所期望的系统行为 | |
非功能性需求(质量特征,限制条件) | 质量特征和限制性条件经常以自然语言文字的方式来描述。但是这也经常导致缺少精确描述或是描述得不完整 |
关于图的详细定义、图式、方法、使用,参考另一本书的笔记《软件需求与可视化模型》
发表回复