type
status
date
slug
summary
tags
category
icon
password
3.1 需求分析的概念
- 需求分析的定义:确定系统必须具有的功能和性能,系统要求的运行环境,并且预测系统发展的前景。
- 换句话说需求就是以一种清晰、简洁、一致且无二义性的方式,对一个待开发系统中各个有意义方面的陈述的一个集合。(这一句话讲的什么狗屎)
3.2 需求的获取
3.2.1 需求获取概念
- 需求获取的定义:软件需求获取指的是
- 软件需求的来源
- 软件工程师收集这些软件需求的方法
3.2.2 需求的类型
- 功能性需求:描述系统应该做什么,即为用户和其它系统完成的功能、提供的服务(关注的是功能方面的需求)
- 非功能性需求:必须遵循的标准,外部界面的细节,实现的约束条件,质量属性等等(关注的是质量方面的需求)
3.2.3 需求的来源
- 用户
- 投资者
- 运行环境
- 组织环境(这里的组织理解为是软件开发团队,leader可能会提出一些需求)
- 领域知识(也就是开发软件的时候需要了解该软件应用领域的知识)
3.2.4 需求获取技术
- 采访(也就是开发者和客户之间进行沟通)
- 会议(还是沟通的问题)
- 设定情景(用例)
- 原型(给一个部分开发的产品给用户看是不是符合需求)
- 观察商业过程和工作流(会影响到软件的交付时间等,进而对软件的开发提出需求,如需要做的快一点)
3.2.5 面临的挑战
- 需求获取面临的挑战
- 客户说不清楚需求
- 需求易变性
- 问题的复杂性和对问题空间理解的不完备性与不一致性(开发者和用户的理解不同)
- 解决需求获取挑战的一些经验
- 明确哪些需求是稳定的,哪些需求是不稳定的,将工作重心放在稳定的需求上
- 在合同中一定要说清楚“做什么”和“不做什么”
3.2.6 需求诱导(沟通)十原则
- 倾听
- 有准备的沟通
- 需要有人推动
- 最好当面沟通
- 记录所有决定
- 保持通力协作
- 聚焦并协调话题
- 采用图形表示
- 继续前进原则(遇到困难先跳过)
- 谈判双赢原则
3.3 需求分析/管理的过程
3.3.1 需求分析和管理的概念及步骤
- 需求分析/管理的过程主要有五个步骤
- 如下图:
主要流程就是:需求获取->需求提炼->需求描述->需求验证。在这些阶段之间还可能出现需求变更
3.3.2 需求提炼
- 需求提炼的概念:对应用问题及环境的理解和分析,为问题涉及的信息、功能及系统行为建立模型。将用户需求精确化、完全化。
- 需求提炼的主要内容
- 需求提炼的核心在于建立分析模型。
- 需求提炼采用多种形式描述需求,通过建立需求的多种视图,揭示出一些更深的问题。
- 需求提炼还包括与客户的交流以澄清某些易混淆的问题,并明确哪些需求更为重要,其目的是确保所有风险承担者尽早地对项目达成共识并对将来的产品有个相同而清晰的认识
- 下面是一个需求提炼过程建立的模型(这里就可以理解到,需求提炼实际上就是把用户描述的需求抽象成一种模型,或者说图形)
3.3.3 需求描述:规格说明书
- 软件需求规格说明书:软件系统的需求规格说明,是对待开发系统的行为的完整描述。它包含了功能性需求和非功能性需求
- 需求描述的意义
- 需求分析(注意这里说的需求分析就不是需求提炼的别名了,而是整个需求分析的过程)工作完成的一个基本标志是形成了一份完整的、规范的需求规格说明书。
- 需求规格说明书的编制是为了使用户和软件开发者双方对该软件的初始规定有一个共同的理解,使之成为整个开发工作的基础。
3.3.4 需求确认(需求确认)
- 需求确认(需求验证)的意义:如果在后续的开发或当系统投入使用时才发现需求文档中的错误,就会导致更大代价的返工
- 需求验证的工作:对需求文档需执行以下类型的检查:
- 有效性检查:检查不同用户使用不同功能的有效性
- 一致性检查:在文档中,需求之间不应该冲突
- 完备性检查:需求文档应该包括所有用户想要的功能和约束
- 现实性检查:检查保证能利用现有技术实现需求
- 需求验证技术
- 需求评审
- 利用原型检验系统是否符合用户的真正需要
- 对每个需求编写概念性的测试用例。
- 编写用户手册。用浅显易懂的语言描述用户可见的功能。
- 自动的一致性分析。可用CASE工具检验需求模型的一致性。
3.3.5 需求变更管理的过程
如下图(也就是层层下降,从需求提出方一层层到修改层):
3.4 需求分析的任务
- 建立分析模型(在需求提炼阶段完成)
- 编写需求说明(在需求描述阶段完成)
3.5 软件需求规格文档编制
与需求描述有关
- 软件需求规格说明书的编制过程
- 识别主要客户和共利益者
- 与主要客户会谈“上下文无关的问题”,以确定
- 业务需要和商业价值
- 最终用户的特性\需要
- 需要的用户可见输出
- 业务约束
- 写一页项目范围的说明
- 评审范围说明,并应客户要求做出相应修改
- 与客户/最终用户进行协作,确定:
- 采用标准格式记录客户可见的使用场景
- 输入和输出
- 重要的软件特性、功能和行为
- 客户定义的商业风险
- 描述场景、输入/输出、特性/功能以及风险
- 与客户细化场景、输入/输出、特性/功能以及风险
- 为每个用户场景、特性、功能和行为分配客户定义的优先级
- 回顾搜集的所有信息并修订
- 为计划活动做准备
- 软件需求规格说明的原则
- 从现实中分离功能,即描述要“做什么”而不是“怎样实现”
- 要求使用面向处理的规格说明语言(或称系统定义语言)
- 如果被开发软件只是一个大系统中的一个元素,那么整个大系统也包括在规格说明的描述之中
- 规格说明必须包括系统运行环境
- 规格说明必须是一个认识模型
- 规格说明必须是可操作的
- 规格说明必须容许不完备性并允许扩充(验证的时候可以接受有不完备性,但是要能够进行扩充)
- 规格说明必须局部化和松散耦合
3.6 需求分析模型概述
- 需求分析模型的分类
- 面向过程分析模型:其基本思想是用系统工程的思想和工程化的方法,根据用户至上的原则,自始自终按照结构化、模块化,自顶向下地对系统进行分析与设计
- 面向对象分析模型:由5个层次(主题层、对象类层、结构层、属性层和服务层)和5个活动(定义主题、标识对象类、标识结构、定义属性和定义服务)组成。
- 需求分析模型的描述工具(了解即可,后面会详细介绍)
- 面向过程分析模型
- 数据模型:实体联系图、数据字典
- 功能模型:数据流图
- 行为模型:状态变迁图、状态图(自动机?状态转换图?)
- 面向对象分析模型
- 数据模型:类图、类关系图
- 功能模型:用例图
- 行为模型:活动图、时序图(顺序图)、协作图
- 总结:描述系统行为的就是面向过程的分析模型的描述工具;描述对象(包括用户等)行为的就是面向对象的分析模型的描述工具
3.7 面向过程分析方法——结构化分析方法
结构化方法(实际上就是面向过程)和面向对象方法都是软件工程方法
- 结构化分析方法概述
- 面向数据流进行需求分析的方法
- 结构化分析方法适合于数据处理类型软件的需求分析
- 具体来说,结构化分析方法就是用抽象模型的概念,按照软件内部数据传递、变换的关系,自顶向下逐层分解,直到找到满足功能要求的所有可实现的软件为止
3.8 数据流图
3.8.1 数据流图的符号
数据流中使用到的符号如下图(后面会对每一个符号做详细的解释)
注意:数据存储文件除了左边的画法,还可以是右边的画法,也就是只两道杠
下面给出一个数据流图的示例便于理解这些符号
其中储户是数据的起点,日历是数据的重点,所以是采用方框来表示;账卡和存折都是存储数据的地方,所以使用两道杠来表示;校验、付款、登录等步骤都是在处理信息,所以使用圆形来表示;剩下的所有箭头都是信息在传递,所以采用数据流的符号——箭头来表示
3.8.2 数据流图的层次结构
反映了结构化分析方法中提到的自顶向下不断细化
- 在多层数据流图中,顶层流图仅包含一个加工(也就是只有一个圈圈),它代表被开发系统。它的输入流是该系统的输入数据,输出流是系统所输出数据
- 中间层流图则表示对其上层父图的细化。它的每一加工可能继续细化,形成子图
- 底层流图是指其加工不需再做分解的数据流图,它处在最底层
如下图:
3.8.3 数据加工
关于数据流图中的数据加工符号(也就是圈圈)
- 数据加工符号
- 数据加工:表示对数据进行的操作, 如“处理选课单” 、 “产生发票”等
- 加工的编号,说明这个加工在层次分解中的位置 (在分层DFD中才有)
- 如下图:
其中0就是代表当前数据加工是分层DFD中的第0个加工(也就是在顶层。通常通过1.1等表示是第几层第几个数据加工),然后对数据的操作就是仓库管理系统(具体如何取名看下一点)
- 加工的命名
- 顶层的加工名就是整个系统项目的名字(所以上面的示例中的数据加工的名字是仓库管理系统)
- 尽量最好使用动宾词组,也可用主谓词组
- 不要使用空洞的动词(如处理等)
3.8.4 外部实体
对应着数据流图中的外部实体(也就是数据源或者数据终点,就是方框)
- 外部实体简介(有点像用例图中的actor)
- 位于系统之外的信息提供者或使用者,称为外部实体。即存在于系统之外的人员或组织。如“学务科”等
- 说明数据输入的源点(数据源)或数据输出的终点(数据终点)
- 起到更好的理解作用,但不是系统中的事物
3.8.5 数据流
对应着数据流图中的数据流,也就是箭头
- 数据流简介
- 表示数据(命名)和数据流向(箭头), 由一组固定成分的数据组成 如“选课单”由“学号、姓名、课程编号、课程名”等成分组成
- 数据流可从加工流向加工,也可在加工与数据存储或外部项之间流动;两个加工之间可有多股数据流
- 数据流的命名规则
- 用名词,不要使用意义空洞的名词(因为数据都是一个事物,所以是使用名词;但是不能简单地使用“数据”作为数据流的命名)
- 尽量使用现实系统已有名字(说白了就是要贴近现实)
- 数据流与加工的关系
- 如下图
什么逻辑门。如果没有符号就代表或;如果有*代表与;如果有异或符号就代表异或
- 绘制数据流图的数据流时的注意事项
- 不要把控制流当成数据流(这个其实很好区别吧,控制流是一个动作,但是数据流就是单纯的数据。而且在数据流图中没有控制流,只有数据加工)
- 如下图:
- 不要标出激发条件(也就是不需要写限制条件)
如下图:
综上可以得出:数据流图只在乎数据实体的流向,并不在乎限制条件和一些多余的反馈信息
3.8.6 数据存储
- 数据存储简介
- 表示需要保存的数据流向, 如“ 学生档案” 、 “课程设置”等
- 此时数据流的流向表示数据是存储还是读出
- 分层数据流程图中,数据存储一般局限在某一层或某几层(也就是在层次数据流图中只有某些层能做存储)
- 命名方法与数据流相似(都是存储数据的东西,所以也是使用名词,但是不能太宽泛,比如“数据库”)
- 如下图:
3.8.7 数据流图示例
- 绘制数据流图的注意事项
- 每个加工至少有一个输入数据流和一个输出数据流(就是加工必须有进有出)
- 数据流必须要么从某个加工流出、要么流入某个加工,而不能直接从外部项流向数据存储等等(也就是说外部实体和数据存储之间不能直接传输数据,必须通过数据加工)。如下图:
这里摆一个例题和答案:
注意:绘制数据流图的时候就采取层次数据流图的画法,自上而下一步步去细分父图(也就是上层图中的某一个数据加工)
3.9 数据流图的改进
3.9.1 数据流图改进的任务
- 检查正确性(最重要的一定是正确性)
- 提高易理解性(数据流图都叫图了怎么能不好理解嘞)
- 重新分解(需要去平衡每一个数据加工的工作量,想办法分解平衡)
下面就从这三个方面详细介绍
3.9.2 检查数据流图的正确性
- 数据守恒
- 某个加工输出的数据并无相应的数据来源,可能是某些数据流被遗漏了
- 如下图:
- 一个加工的输入并没有用到,这不一定是错误。可与用户进一步讨论,是否属于多余的数据流
如下图:
- 数据存储的使用:是否存在“只读不写”或“只写不读”的数据存储 (注意在所有的DFD中检查,因为可能多个数据流图中都有数据存储)
- 父图和子图的平衡:父图和子图的输入输出必须一致
3.9.3 提高数据流图的易读性
也就是上面说道的改善数据流图中的提高易理解性
- 简化加工之间的联系:应尽量减少加工之间输入输出数据流的数目。因为加工之间的数据流越少,各个加工的功能就越相对独立(尝试在需求上就做到强内聚弱耦合。线少了自然就容易理解了)
- 注意分解的均匀:一张图中,如果某些加工已是基本加工(细节),而另一些加工还可进一步分解成三、四层,则应考虑重新分解(此时就是没有将加工分解均匀)
- 适当地命名
- 名字的意义要明确,容易理解
- 如果难以为DFD图中的成分(数据流、加工等)命名,往往说明分解不当, 可考虑重新分解
3.9.4 重新分解数据流图
在画第N层时意识到在第N-1层或第N-2层所犯的错误,此时就需要对第N-1层、第N-2层作重新分解
如下图:
此时发现子图之中加工之间的并没有关联,说明上一层分解错误需要重新分解。这个时候就直接使用子图来代替父图中的加工,然后把生成的图分成几个部分(这就是在重新分解了),使得输入输出最少;最后再将划分出来的几个加工重新在父图中创建加工,然后原子图的加工就分到对应的加工的子图中
3.9.5 检查数据流图的原则
- 数据流图上所有图形符号只限于前述四种基本图形元素
- 数据流图的主图必须包括前述四种基本元素,缺一不可
- 数据流图的主图上的数据流必须封闭在外部实体之间
- 每个加工至少有一个输入数据流和一个输出数据流
- 在数据流图中,需按层给加工框编号。编号表明该加工所处层次及上下层的亲子关系(还有在当前层是第几个加工)
- 规定任何一个数据流子图必须与它上一层的一个加工对应,两者的输入数据流和输出数据流必须一致。此即父图与子图的平衡
- 图上每个元素都必须有名字
- 数据流图中不可夹带控制流
- 初画时可以忽略琐碎的细节,以集中精力于主要数据流
3.10 什么是对象
- 对象的概念:在现实世界中有意义的、与所要解决的问题有关系的任何事物都可以作为对象
3.11 面向对象的软件开发模型
也就是上面提到的一些面向对象的软件开发模型的工具
- 面向对象的数据模型的描述工具:类图、类关系图
- 描述系统数据结构(类就是一种数据结构)的对象模型
- 面向对象的功能模型的描述工具:用例图
- 描述系统功能(用例图中的每一个用例都代表了系统的一个功能)
- 面向对象的行为模型的描述工具:活动图、顺序图、状态图
- 描述系统控制结构(就是在描述控制流。想想顺序图的控制关系)
3.12 用例图
用例建模用于描述系统需求,把系统当作黑盒(就不关注系统的过程了),从用户的角度,描述系统的场景(上面的数据流图就是把系统的处理过程写的很清楚,所以是面向过程的分析模型;但是用例图是从用户的角度来描述系统的适用,并不关注系统的过程而是关注用户这个对象,所以是面向对象的需求提炼的功能模型)
3.12.1 用例图的符号
- 参与者:是指外部用户或外部实体在系统中扮演的角色。可以是一个人、一个计算机子系统、硬件设备或者时间等角色(有点像数据流图中的外部实体)。符号如下图:
- 用例:对一组动作序列(这里就可以看出来用例图是面向对象的了,因为如果是数据流图的话还需要继续细化,但是用例图就不用,因为这个已经是用户能够观察到的最小的事情了)的描述,系统通过执行这一组动作序列为参与者产生一个可观察的结果。用例名往往用动宾结构命名(有点像数据流图中的数据加工),符号如下图:
- 执行关联: 参与者(Actor )执行用例(Use Case)之间的关系,符号如下图(就是一根线把参与者和用例连起来罢了):
3.12.2 用例建模的过程
- 确定谁会直接使用该系统。这些都是参与者(Actor)。(也就是找出所有的参与者)
- 选取其中一个参与者。
- 定义该参与者希望系统做什么,参与者希望系统做的每件事成为一个用例。
- 对每件事来说,何时参与者会使用系统,通常会发生什么,这就是用例的基本过程。
- 描述该用例的基本过程。
- 考虑一些可变情况,把他们创建为扩展用例(就是在原来的用例基础上去补充,后面也会用到)
- 复审不同用例的描述,找出其中的相同点,抽出相同点作为共同的用例。(也就是抽取化简的过程)
- 重复步骤2~7找出每一个用例
3.12.3 用例图中的参与者
- 参与者:参与者(actor)是指系统以外的、需要使用系统或与系统交互的东西,包括人、设备、外部系统等。(就像数据流图中的外部实体)
- 参与者的表示方法如下(通常使用第一种形式):
- 如何确定参与者(实际上只要根据题目中的描述判断谁需要使用当前的系统即可)
- 在获取用例前首先要确定系统的参与者,开发人员可以通过回答以下的问题来寻找系统的参与者。
- 谁将使用该系统的主要功能?
- 谁将需要该系统的支持以完成其工作?
- 谁将需要维护、管理该系统,以及保持该系统处于工作状态?
- 系统需要处理哪些硬件设备?
- 与该系统交互的是什么系统?
- 谁或什么系统对本系统产生的结果感兴趣?
例子如下:
3.12.4 用例图中的用例
- 用例的定义(跟上面用例图中的定义是一样的):对一组动作序列的描述,系统通过执行这一组动作序列为参与者产生一个可观察的结果
- 用例的特征
- 说明了系统具有的一种行为模式(因为描述的是系统的一串动作)
- 说明了一个参与者与系统执行的一个相关的事件序列(因为动作的双方是系统和用户)
- 提供了一种获取系统需求的方法(用例实际上就是一个功能需求)
- 提供了一种与最终的用户和领域专家进行沟通的方法(用例图是面向对象的,所以比较好懂)
- 提供了一种测试系统的方法(根据用例进行测试)
- 用例的表示(跟上面用例图中说的是一样的)
- 如何获取用例(实际上只需要根据题目的描述然后找出系统要做的事就好了,通常是直接抓动词就能抓到)
- 参与者希望系统执行什么任务?
- 参与者在系统中访问哪些信息(创建、存储、修改、删除等)?
- 需要将哪些外界信息提供给系统
- 需要将系统的什么事情告诉参与者(这个就是从系统中返回信息,在题干中也会有描述的)
- 如何维护系统
3.12.5 用例图中的系统和关联
- 系统:用于界定系统功能范围,描述该系统功能的用例都置于其中,而描述外部实体的参与者都置于其外(画用例图的时候都把系统画出来)
- 关联:连接参与者和用例,表示参与者所代表的系统外部实体与该用例所描述的系统需求有关
3.12.6 用例扩展
对应了用例建模过程(实际上就是绘制用例图)中所说道的扩展用例
上面涉及到了用例之间的关系,详见下一节
这里可以发现扩展关系实际上是原用例中没有的但是在使用原用例的时候可能会出现某些情况会执行扩展用例(如上图中的购买饮料的时候用户可能想要买散装饮料。但实际上这个更像是继承关系。不是包含关系是因为购买饮料并不一定会执行售散装饮料这个用例),但是包含关系就是说原用例中是有某个用例的(或者说执行原用例的时候会执行某一个子用例)
3.13 用例图中的关系
3.13.1 用例图中的几类关系
- 关联
- 泛化
- 包含
- 扩展
3.13.2 用例间的关系:关联
- 关联:表示参与者与用例之间的通信,任何一方都可发送或接受消息。
- 关联关系的符号表示(跟上面的用例图总述是一样的)及含义:使用没有三角形的箭头表示,箭头指向信息接收方(并不一定是从参与者指向用例)
- 如下图:
PS:参与者可以参与多个用例,由此形成子系统(应该用不太到)
3.13.3 用例间的关系:泛化
- 泛化(is a kind of好理解一点):就是通常理解的继承关系。子用例和父用例相似,但表现出更特别的行为;子用例将继承父用例的所有结构、行为和关系。子用例可以使用父用例的一段行为,也可以重载它。父用例通常是抽象的。
- 用例之间的is a kind of 关系,表示用例之间的场景共享;Actor之间的 is a kind of关系,一般描述职责共享(参与者之间也可以有泛化关系)
- 泛化关系的符号表示及含义:箭头指向的是父用例(或者是父参与者),也就是指向上层。也可以从英文角度理解,电话订票is a kind of订票,所以是从电话订票指向订票
- 如下图:
3.13.4 用例间的关系:包含
- 包含:包含关系用来把一个较复杂用例所表示的功能分解(说明原来的用例中是有这些小用例的,所以执行大用例的时候一定会执行这些小用例)成较小的步骤。一个用例可以包含另外一个用例
- 包含关系的符号表示及含义:指向分解出来的功能用例(指向小的。同样也可以通过英文来理解,维护数据库include修改数据,所以是从维护数据库指向修改数据)
- 如下图:
3.13.5 用例间的关系:扩展
- 扩展:扩展关系是指用例功能的延伸(所以说新用例并不是原用例的一个部分,如下例中买一送一就不是买电器的一个步骤/部分),相当于为基础用例提供一个附加功能。由一个用例的扩展点可以扩展出另外一个用例
- 扩展关系的符号表示及含义:指向基础用例(也可以通过英文来理解,买一送一extend了买电器,所以是从买一送一指向买电器)
- 如下图:
3.13.6 不同类型的区别
主要是讨论包含和泛化之间的区别
- 在扩展关系中,一个基本用例执行时,可以执行、也可以不执行扩展用例部分(也就是原用例的执行过程中可能会执行扩展用例)
- 在包含关系中,在执行基本用例时,一定会执行包含用例部分(也就是大用例的执行过程中一定会执行小用例)
下面给出四个关系的总结
3.13.7 用例图示例
摆一个例题
总结:并不是题干中出现“系统”等字眼的部分才跟软件系统有关系。应该是所有有可能跟系统有关系的地方都需要设计成一个用例(如上图中的设备分配,题干中只是提到了教务处要分配设备,但是并没有提到这个分配设备是在系统上完成的。但是实际情应该是有可能在系统上完成,如需要将设备信息和教学楼信息在系统上绑定等。所以需要把分配设备设计成一个用例),这样设计出来的用例才足够详细
- 作者:Noah
- 链接:https://imnoah.top/article/SoftwareEn/Chapter3
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。