第六章 系统开发基础
6.1 软件工程
6.1.1 软件的基本生存周期
6.1.2 软件过程
软件过程改进-CMM
- 初始级(1级):杂乱无章,甚至混乱,几乎没有明确定义的步骤,项目的成功完全依赖个人的努力和英雄式核心任务的作用。
- 可重复级(2级):建立了基本的项目管理过程和实践来跟踪项目费用、进度和功能特性,有必要的过程准则来重复以前在同类项目中成功。
- 已定义级(3级):管理和工程两方面的软件过程已经文档化、标准化,并综合成整个软件开发组织的标准过程。
- 已管理级(4级):制定了软件过程和产品质量的详细度量标准。
- 优化级(5级):加强了定量分析,通过来自过程质量反馈和来自己新观念、新技术的反馈使过程能不断持续地改进。
软件过程改进-CMMI
CMMI阶段式模型
等级越高,成熟度越高,风险越低
CMMI连续式模型
等级CL | 关键字 |
---|---|
CL0(未完成的) | 未执行或未得到 |
CL1(已执行的) | 可标识的输入工作产品转换成可标识的输出工作产品 |
CL2(已管理的) | 已管理的过程的制度化 |
CL3(已定义级的) | 已定义的过程的制度化 |
CL4(定量管理的) | 可定量管理的过程的制度化 |
CL5(优化的) | 量化(统计学)手段改变和优化过程域 |
6.2 软件开发方法
6.2.1 结构化方法(面向过程)-需求明确
- 用户至上
- 严格区分工作阶段,每阶段有任务和结果(规划→需求分解→设计→实现/编码→测试→维护)
- 规划:规划说明书
- 需求分解:需求分析说明书
- 设计:软件设计说明书,包括概要说明书/详细设计说明书
- 编码:源代码
- 测试:测试计划/测试报告
- 运维:运维报告
- 强调系统开发过程的整体性和全局性
- 系统开发过程工程化,文档资料标准化
- 自顶向下,逐步分解(求精)
6.2.2 原型法(渐进明晰)-需求不明确,帮助用户明确需求(原型图)
6.2.3 面向对象方法-复杂大项目
- 更好的复用性
- 关键在于建立一个全面、合理、统一的模型
- 分析、设计、实现三个阶段,界限不明确
6.2.4 面向服务方法(更高级别的面向对象)
- 抽象级别:操作、服务、业务流程
6.2.5 Jackson 面向数据结构
–
6.3 关键开发模型※
适用场景、不适用场景
6.3.1 瀑布模型与V模型※
瀑布模型
特点:已文档作为驱动,适合于软件需求很明确的软件项目(结构化方法),一旦某个阶段出现问题,则项目全部需要推倒重新规划执行
V模型
特点:将验证确认活动应用于早期软件工程中,测试贯穿始终
6.3.2 演化模型(原型模型、螺旋模型)
演化模型是迭代的过程模型,使得软件开发人员能够逐步开发出更完整的软件版本。演化模型特别适用于对软件需求缺乏准确认识的情况。
原型模型
螺旋模型
瀑布模型和演化模型结合,加入风险分析。特别适用于庞大、复杂并且具有高风险的系统。
6.3.3 增量模型
第一个增量往往是核心产品。将需求分段为一系列增量产品,每一增量可以分别开发。
产品一般遵循28原则,主要功能(常用功能)占用20%,该部分为产品核心;
缺点:定义产品核心增量困难(模块划分困难),对开发人员要求比较高;
6.3.4 喷泉模型
以用户需求为动力,以对象作为驱动的模型,适合于面向对象的开发方法。
特点:迭代无间隙
6.3.5 统一过程UP/RUP
特点:用例驱动,以架构为中心迭代和增量
- 初始/初启
- 确定项目范围和边界
- 识别系统的关键用例
- 展现系统的候选架构
- 估计项目费用和时间
- 评估项目风险
- 细化/精化
- 分析系统问题领域
- 建立软件架构基础
- 淘汰最高分线元素
- 构建
- 开发剩余的构件/组件
- 构件组装与测试(α测试-开发环境)
- 交付
- 进行β测试(生产环境)
- 制作发布版本
- 用户文档定稿
- 确认新系统
- 培训、调正产品
6.3.6 敏捷方法
基本原则
- 短平快的会议
- 小型版本发布
- 较少的文档
- 合作为重
- 客户直接参与
- 自动化测试
- 适应性计划调整
- 结对编程(一人写,一人看)
- 测试驱动开发
- 持续集成
- 重构
总体目标是通过“尽可能早地、持续地对有价值地软件地交付”使客户满意。
适用于:“小步快跑”地思想,适合小项目小团队。
极限编程XP
4大价值观
- 沟通
- 简单
- 反馈
- 勇气
5大原则
- 快速反馈
- 简单性假设
- 逐步修改
- 提倡更改
- 优质工作
12个最佳实践
- 计划游戏:快读制定计划、随着细节地不断变化而改善
- 小型发布:系统地设计要能够尽可能早地交付
- 隐喻:找到合适地比喻传达信息
- 简单设计:只处理当前地需求,使设计保持简单
- 测试先行:先写测试代码,然后再编写程序
- 重构:重新审视需求和设计,重新明确地描述他们以符合新地和现有地需求
- 结对编程
- 集体代码所有制
- 持续集成:可以按日甚至按小时为客户提供可运行地版本
- 每周工作40小时
- 现场客户:系统最终用户代表应该全程配合XP团队
- 编码标准
敏捷开发方法
敏捷方法 | 特点 |
---|---|
极限编程XP**** | 3大价值观、5大原则、12个最佳实践 |
水晶法(Crystal) | 认为每一个不同的项目都需要一套不同地策略、约定和方法论,认为人对软件质量有重要的影响(以人为本),因此随着项目质量和开发人员素质的提高,项目和过程的质量也随之提高。通过更好地交流和经常性地交付,软件生产力得到提高。 |
开放式源码 | 程序开发人员再地域上分布很广 |
并列争球法(SCRUM) | 把每30天一次地迭代称为一个“冲刺”,并按需求地优先级来实现产品。多个自组织和自治地小组并行地递增实现产品。协调是通过简短地日常情况会议来进行,就像橄榄球重地“并列争球” |
功用驱动开发方法FDD | 首席程序员(不需要敲代码,需掌握开发方向)和“类程序员” |
自适应软件开发ASD | 核心是三个非线性的、重叠的开发阶段:猜测、合作与学习。ASD有6个基本的原则:有一个使命作为指导;特征被视为客户价值的关键点;过程中等待是很重要的,因此“重做“与“做”同样关键;变化不被视为改正,而是被视为对软件开发实际情况的调整;确定的交付时间迫使开发人员认真考虑每一个生产的版本的关键需求;风险也包含其中。 |
6.4 需求分析
6.4.1 需求分析的概念
需求的任务(搞清楚用户的需求是什么)
需求的过程
- 问题识别
- 分析与综合
- 编制需求分析文档(需求规格说明书SRS)
- 需求分析与评审(需求规格文档制定后需要客户确认)
结构化分析的结果:一套分层的数据流图,一本数据字典,一组小说明(也称加工逻辑说明)、补充材料
6.4.2 需求的分类
6.4.3 需求分析的工具
数据流图(DFD)※ 15分
基本特点:自顶向下,从抽象到具体
元素 | 说明 | 图元 |
---|---|---|
数据流 | 由一组固定陈芬的数据组成,表示数据的流向。每个数据流通常有一个合适的名词,反映数据流的含义(数据流必须和加工相关,即从加工流向加工、数据源向加工或加工流向数据源。) | → |
加工 | 加工描述了输入数据流到输出数据流之间的变换,也就是输入数据流做了什么处理后变成了输出数据流 | ⚪、圆角矩形 |
数据存储(文件) | 用来表示暂时存储的数据,每个文件都有名字。流向文件的数据流表示写文件,流出的表示读文件 | = |
外部实体 | 指存在于软件系统外的人员或组织 | 矩形 |
考点
- 补充实体名
- 补充存储名
- 补充加工名
- 补充数据流
数据平衡原则
- 父图与子图之间的平衡
- 父图与子图之间平衡是指任何一张DFD子图边界上的输入/输出数据流必须与其父图对应加工的输入/输出数据保持一致。如果父图中某个加工的一条数据流对应于子图中的几条数据流,而子图中的组成这些数据流的数据项全体正好等于父图中的这条数据流,那么他们仍然是平衡的;
- 例如:数据流图A,输入/输出为P1和P2,子图B的输入/输出为P3和P4,子图C的输入,输出为P5,P6和P7,P8,P9;若P1=P3&&P2=P4,则父图A和子图B之间是平衡的,若P1=P5+P6&&P2=P7+P8+P9,则父图A和子图C之间是平衡的
- 子图内平衡
- 常见3中错误
- 加工只有输入没有输出,称之为“黑洞”;
- 加工只有输出没有输入,称之为“奇迹”;
- 加工中输入不足以产出输入,称之为“灰洞”;
- 常见3中错误
解题技巧
- 详细分析试题说明
- 利用数据平衡原则
1、补充实体
实体可能是:
- 人物角色:如客户、管理员、主管、经理、老师、学生
- 组织架构:如银行、供应商、募捐机构
- 外部系统:如银行系统、工资系统、后台数据库(当要开发的是中间件时)
2、补充存储
存储的文字方面特征:“**文件”、“**表”、“**库”、“**清单”、“**档案”
3、补充数据流
- 数据平衡原则
- 顶层图与0图对比,是否有顶层图有,但0图无的数据流,或反之。
- 检查途中的每个加工,是否存在只有入没有出,或只有出没有入,或根据输入的数据无法产生对应的输出的情况。
- 按题目说明与图进行匹配
- 说明中的每一句话,都能与图中有对应关系,当把说明中的实体与数据流标识出来之后,容易缩小对用范围,找出纰漏。
4、补充加工名
- “动词”+“名词”:如 生成报告、发出通知、批改作业、记录分数、物流跟踪、用户管理
例题:
阅读下列说明,回答问题1至问题4,将解答填入答题纸的对应栏内。
【说明】某证券交易所为了方便提供证券交易服务,欲开发一证券交易平台,该平台的主要功能如下:
(1)开户。根据客户服务助理提交的开户信息,进行开户,并将客户信息存入客户记录中,账户信息(余额等)存入账户记录中;
(2)存款。客户可以向其账户中存款,根据存款金额修改账户余额;
(3)取款。客户可以从其账户中取款,根据取款金额修改账户余额;
(4)证券交易。客户和经纪人均可以进行证券交易(客户通过在线方式,经纪人通过电话),将交易信息存入交易记录中;
(5)检查交易。平台从交易记录中读取交易信息,将交易明细返回给客户。
现采用结构化方法对该证券交易平台进行分析与设计,获得如图1-1所示的上下文数据流图和图1-2所示的0层数据流图。
【问题1】(3分):使用说明中的词语,给出图1-1中的实体E1-E3的名称。
【问题2】(3分):使用说明中的词语,给出图1-2中的数据存储D1-D3的名称。
【问题3】(4分):根据说明和图中的术语,补充图1-2中缺失的数据流及其起点和终点。
【问题4】(5分):实际的证券交易通常是在证券交易中心完成的,因此,该平台的“证券交易”功能需将交易信息传递给证券交易中心。针对这个功能需求,需要对图1-1和图1-2进行哪些修改,请用200字以内的文字加以说明。
例题:
阅读下列说明,回答问题1至问题4,将解答填入答题纸的对应栏内。
【说明】
某医疗护理机构为老年人或有护理需求者提供专业护理,现欲开发一基于Web的医疗管理系统,以改善医疗护理效率。该系统的主要功能如下:
(1)通用信息查询。客户提交通用信息查询请求,查询通用信息表,返回查询结果。
(2)医生聘用。医生提出应聘/辞职申请,交由主管进行聘用/解聘审批,更新医生表,并给医生反馈聘用/解聘结果;删除解聘医生的出诊安排。
(3)预约处理。医生安排出诊时间,存入医生出诊时间表;根据客户提交的预约查询请求,查询在职医生及其出诊时间等预约所需数据并返回;创建预约,提交预约请求,在预约表中新增预约记录,更新所约医生出诊时间并给医生发送预约通知;给客户反馈预约结果。
(4)药品管理。医生提交处方,根据药品名称从药品数据中查询相关药品库存信息,开出药品,更新对应药品的库存以及预约表中的治疗信息;给医生发送”药品已开出”反馈。
(5)报表创建。根据主管提交的报表查询请求(报表类型和时间段),从预约数据、通用信息、药品库存数据、医生以及医生出诊时间中进行查询,生成报表返回给主管。
现采用结构化方法对医疗管理系统进行分析与设计,获得如图1-1所示的上下文数据流图和图1-2所示的0层数据流图。
【问题1】(3分)
使用说明中的词语,给出图1-1中的实体E1~E3的名称。
【问题2】(5分)
使用说明中的词语,给出图1-2中的数据存储D1~D5的名称。
【问题3】(4分)
使用说明和图中术语,补充图1-2中缺失的数据流及其起点和终点。
【问题4】(3分)
使用说明中的词语,说明“预约处理”可以分解为哪些子加工并说明建模图1-1和图1-2是如何保持数据流图平衡。
数据字典(DD)※
符号 | 含义 | 举例说明 |
---|---|---|
= | 被定义 | |
+ | 与 | x=a+b,表示x由a和b组成 |
[…, …]或[…|…] | 或 | x=[a, b], x=[a|b],表示x由a或由b组成 |
{…} | 重复 | x={a},表示x由0个或多个a组成 |
(…) | 可选 | x=(a),表示a可在x中出现,也可以不出现 |
数据字典有以下4类条目:数据流、数据项、数据存储和基本加工。(源点和终点不再系统之内,不在字典中说明)
加工逻辑的描述
常用的加工逻辑描述方法有结构化语言、判定表和判定树3种。
结构化语言
判定表
判定树
6.5 系统设计
6.5.1 系统设计概述
软件设计的任务与活动
概要设计:划分子系统/模块,给子系统/模块分配任务/功能
详细设计:子系统/模块内部具体实现
- 体系结构设计(架构设计):定义软件系统各主要部件之间的关系。(概要)
- 数据设计:基于E-R图确定软件涉及的文件系统的结构及数据库的表结构。
- 接口设计(人机界面设计):软件内部,软件和操作系统间以及软件和人之间如何通信。
- 过程设计:系统结构部件转换成软件的过程描述。确定软件各个组成部分内的算法及内部数据结构,并选定某种过程的表达形式来描述各种算法。(详细)
应用的工具
- IPO图
- PDL
- PAD
- 程序流程图
- N/S盒图
6.5.2 模块设计
- 保持模块的大小适中
- 尽可能减少调用的深度
- 多扇入,少扇出(数量适中)
- 单入口,单出口
- 模块的作用域(控制域)应该在模块之内
- 功能应该是可预测的
模块设计原则(高内聚,低耦合)
高内聚
内聚类型 | 描述 |
---|---|
功能内聚 | 完成一个单一功能,各个部分协同工作,缺一不可 |
顺序内聚 | 处理元素相关,而且必须顺序执行 |
通信内聚 | 所有处理元素集中在一个数据结构的区域上 |
过程内聚 | 处理元素相关,而且必须按特定的次序执行 |
瞬时内聚(时间内聚) | 所包含的任务必须在同一时间间隔内执行 |
逻辑内聚 | 完成逻辑上相关的一组任务 |
偶然内聚(巧合内聚) | 完成一组没有关系或松散关系的任务 |
低耦合(模块之间的联系)
耦合类型 | 描述 |
---|---|
非直接耦合 | 两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的 |
数据耦合 | 一组模块借助参数表传递简单数据 |
标记耦合 | 一组模块借助参数表传递记录信息(数据结构)(复杂数据) |
控制耦合 | 模块之间传递的信息中包含用于控制模块内部逻辑的信息 |
外部耦合 | 一组模块都访问同一全局简单变量,而且不是通过参数表传递该全局变量的信息 |
公共耦合 | 多个模块都访问同一个公共数据环境 |
内容耦合 | 一个模块直接访问另一个模块的内部数据;一个模块不通过正常入口转到另一个模块的内部; 两个模块有一部分程序代码重叠;一个模块有多个入口 |
6.5.3 人机界面设计
黄金三原则
- 置于用户控制之下
- 减少的记忆负担
- 保持界面的一致性
6.5.4 架构设计
软件架构风格
-
架构设计的一个核心问题是能否达到机构级的软件复用
-
架构风格反映了领域中众多系统所共有的结构和语义特性,并指导如何将各个构件有效地组成一个完整地系统
-
架构风格定义了用于描述系统地属于表和一组指导构件系统地原则
-
数据流风格:批处理序列、管道-过滤器
-
调用/返回风格:主程序/子程序、面向对象、层次结构(MVC、C/S、B/S)
-
独立构件风格:进程通信、事件驱动系统(隐式调用)
-
虚拟机风格:解释器、基于规则地系统
-
仓库风格:数据库系统、超文本系统、黑板系统
数据流风格(对性能没有提升)
批处理哦序列
- 构件为一系列固定顺序地计算单元,构件之间只通过数据传递交互,每个处理步骤是一个独立地程序,每一步必须在其前一步结束后才能开始,数据必须是完整地,以整体地方式传递
管道-过滤器
- 每个构件都有一组输入和输出构件读输入的数好经过内部处理然后产生输出数据流。这个过程通常是通过对输入数据流的变换或计算来完成的,包括通过计算和增加信息以丰富数据、通过浓缩和删除以精简数据、通过改变记录方式以转化数据和递增地转化数据等。这里的构件称为过滤器,连接件就是数据流传输的管道,将一个过滤器的输出传到另一个过滤器的输入。
- 早期编译器就是采用这种架构。要一步一步处理地,均可考虑采取此架构风格。
调用/返回风格(层次结构)
优点
- 这种风格支持基于可增加抽象层地设计,允许将一个复杂问题分解成一个增量步骤序列地实现
- 不同层次处于不同地抽象级别:
- 越靠近底层,抽象级别越高
- 越靠近顶层,抽象级别越低
- 由于每一层最多只影响两层,同时只要给相邻层提供相同地接口,允许每层用不同地方法实现,同样为软件复用提供了强大地支持
缺点
- 并不是每个系统都可以很容易地划分为分层地模式
- 很难找到一个合适的、正确的层次抽象方法
6.6 系统测试
6.6.1 测试的基本概念及分类
软件测试
目的:找到未发现的错误
遵循原则:
- 尽早、不断的进行测试
- 程序员避免测试自己设计的程序
- 既要选择有效、合理的数据,也要选择无效、不合理的数据
- 修改后应进行回归测试
- 尚未发现的错误数量与该程序已发现错误成正比
分类
6.6.2 黑盒测试
等价类划分 | 确定无效与有效等价类 设计用例尽可能多的覆盖有效类 设计用例只覆盖一个无效类 |
---|---|
边界值分析 | 处理边界情况时最容易出错 选取的测试数据应该恰好等于、稍小于或稍大于边界值 |
6.6.3 白盒测试
定义 | |
---|---|
语句覆盖 | 被测试程序中的每条语句至少执行一次。 |
判定覆盖 (分支覆盖) | 被测程序每个判定表达式至少获得一次”真“值和”假“值 |
条件覆盖 | 每一个判定语句中每个逻辑条件的各种可能值至少满足一次 |
判断/条件覆盖 | 判定中每个条件的所有可能取值(真、假)至少出现一次 |
条件组合覆盖 | 每个判定中的各种可能值的组合都至少出现一次 |
路径覆盖 | 覆盖被测试程序中的所有可能路径 |
基本路径测试 | 每条独立路径都执行过(即程序中可执行语句至少执行一次) |
循环覆盖 | 循环中每个条件都得到验证 |
6.6.4 测试阶段划分
- 单元测试:模块测试,模块功能、性能、接口等
- 集成测试:模块间的接口
- 系统测试:真实环境下,验证完整的软件配置项能否和系统正确连接
- 确认测试:验证软件与需求的一致性。内部确认测试、Alpha测试(开发环境)、Beta测试(用户环境),验收测试(外部)
- 回归测试:测试软件变更之后,变更部分的正确性对变更需求的符合性
6.6.5 McCabe复杂度计算
计算有向图G的环路复杂度公式
V
(
G
)
=
m
−
n
+
2
V(G)=m-n+2
V(G)=m−n+2
说明:其中V(G)是有向图G中的环路个数,m是G中的有向弧数,n是G中的节点数。
6.7 软件维护
- 改正性维护:错误已经发生
- 适应性维护:指使应用软件适应信息技术变化和管理需求变化而进行的修改。企业的外部市场环境和管理需求的不断变化也使各级管理人员不断提出新的信息需求。
- 预防性维护:错误尚未发生
- 完善性维护:扩充功能和改善性能而进行的修改,对已有的软件系统增加一些在系统分析和设计阶段中没有规定的功能与性能特征。
软件维护工具:版本控制、文档分析、逆向工程
6.8 软件文档
6.8.1 开发文档(面向开发)
- 可行性研究和项目任务书
- 需求规格说明
- 功能规格说明
- 设计规格说明(包括程序和数据规格说明)
- 开发计划
- 软件集成和测试计划
- 质量保证、标准、进度
- 安全和测试信息
6.8.2 产品文档(面向用户)
- 培训手册
- 参考手册和用户指南
- 软件支持手册
- 产品手册和信息广告
6.8.3 管理文档(面向管理人员)
- 开发过程的每个阶段的进度和进度变更的记录
- 软件变更情况的记录
- 相对于开发的判定记录
- 职责定义