Skip to content

软件工程 第一部分

第一章 绪论

第一节 软件工程概念的提出与发展

软件危机
  1. 软件开发的速度(效率)
  2. 软件制品的质量
  3. 软件开发成本
软件工程

应用计算机科学理论和技术以及工程原则和方法,按预算和进度实现满足用户要求的软件产品的工程,或以此为研究对象的学科。

软件工程的发展
  1. 20世纪60-80年代初

    • 开发模型、开发方法、支持工具
  2. 20世纪80年代末-今

    • 软件复用技术、软件生产管理

第二节 软件开发的本质

软件的概念

软件 = 程序 + 文档

软件开发的目标
  • 映射
  • 将问题域中的概念映射为运营平台层面上的概念

问题域(商品名称、单价、数量、折扣,计算总价、收款)=> 软件开发(系统建模,设计和实现) => 运行平台(硬件、网络、操作系统,程序开发工具、中间件)

软件开发的本质

不同抽象层术语之间的"映射",以及不同抽象层处理逻辑之间的"映射"。

  1. 如何实现这样的映射?

    • 技术问题
  2. 如何管理这样的映射?

    • 过程途径
    • 问题建模
模型的概念

模型是一个抽象,模型是在特定意图下所确定的角度和抽象层次上对物理系统的描述,通常包含对该系统边界的描述,对系统内各模型元素以及它们之间关系的语义描述。

模型的类别
  1. 概念模型:描述软件是什么;
  2. 软件模型:实现概念模型的软件解决方案。包括设计模型、实现模型和部署模型。

小结

  1. 软件危机的出现,导致了软件工程的引入。
  2. 软件开发的本质,实现问题空间的概念和处理逻辑到解空间的概念和处理逻辑之间的映射。
  3. 系统建模是指运用所掌握的知识,通过抽象,给出系统的一个结构。
  4. 模型是一个抽象。
  5. 在软件开发领域,模型有两大类:概念模型和软件模型。

第二章 需求获取

第一节 需求与需求获取

需求的定义

是有关一个"要予构造"的陈述,描述了待开发产品/系统功能能力、性能参数或其它性质。

需求的基本性质
  1. 必要的
  2. 无歧义的
  3. 可测的
  4. 可跟踪的
  5. 可测量的
需求的分类
  1. 功能需求,是整个需求的主体。
  2. 非功能需求:性能需求、外部接口需求、设计约束和质量属性需求。

注:能识别:功能需求、性能需求、接口需求、设计约束(用户接口、硬件接口、软件接口、通信接口、内存约束、运行、地点需求)、质量属性。

需求发现技术
  1. 自悟
  2. 交谈
  3. 观察
  4. 小组会
  5. 提炼

第二节 需求规约(SRS)

需求规约的定义 ★

是一个软件/产品/系统所有需求陈述的正式文档,它表达了一个软件/产品/系统的概念模型。

需求规约的基本性质
  1. 重要性和稳定性程度:对需求进行分级
  2. 可修改的
  3. 完整的:没有被遗漏的需求
  4. 一致的:不存在互斥的需求
需求规约的格式 ★

IEEE标准830-1998(IEEE1998)描述的需求规格说明书模板。

  1. 引言 目的、范围、定义、缩略语、参考文献、概述
  2. 总体描述 产品描述、产品功能、用户特性、约束、假设和依赖
  3. 特定需求 是文档的技术核心
  4. 附录
  5. 索引
需求规约的表达

表达需求的语言

  1. 非形式化的需求规约
  2. 半形式化的需求规约
  3. 形式化的需求规约
需求规约的作用
  1. 需求规约是软件开发组织和用户之间一份事实上的技术合同书,是产品功能及其环境的体现。
  2. 需求规约是一个管理控制点。
  3. 对于产品/系统而设计,需求规约是一个是正式的、受控的起始点。
  4. 需求规约是创建产品验收计划和用户指南的基础。

第三章 结构化方法

第一节 结构化需求分析

  • DFD图(流程图)
  • 数据字典
  • 决策树、判定表
需求分析面临的挑战
  • 问题空间理解
  • 人与人之间的通信,"有效沟通"
  • 需求的变化性
需求技术的基本特征
  • 提供方便通信的机制
  • 鼓励需求分析人员使用问题空间的术语思考问题,编写文档
  • 提供定义系统边界的方法
  • 提供支持抽象的基本机制
  • 为需求分析人员提供多种可供选择的方案
  • 提供特定的技术,适应需求的变化
需求分析中的基本术语
  • 数据(Data) 客观事物的一种表示
  • 信息(Information) 具有特定语义的数据
  • 数据是信息的载体
  • 数据流(Flow) 数据的流动
  • 加工 数据变换单元
  • 数据存储
  • 数据源和数据潭
表示方法

数据流:------->(箭线) 加工:椭圆 数据存储:====(两条平行线,文字写在两线之间) 数据源和数据潭:矩形

系统功能模型表示方法
  1. 数据流图(DFD图) 一种表示数据变换的图形化工具
  2. 数据流程图的元素 数据源/数据潭,数据流,数据加工,数据存储
建模过程
1.数据流图
  1. 自顶向下,逐步求精
  2. 建立系统环境图
  3. 0层图:从0层图开始对流程图中的要素编号
    • 要对处理编号:1、2、3...
  4. 1层图...
    • 编号规则:1.1、1.2、2.1...
2.数据字典
  • 定义数据流程图中所有数据流和数据存储的数据结构。
  • 顺序结构:+
  • 选择结构:|
  • 重复结构:{}
  • 子界:m...n
3.加工的描述
  1. 判定表 判定表(Decision Table)也称为决策表,是一个二维表,它说明了每一种条件组合所产生的结果。

    决策规划号12345678
    条件1YYYYNNNN
    条件2YNNNYYNN
    条件3YNYNYNYN
    行动1XX
    行动2XXXX
    行动3XX

    分为四个象限(quadrants):

    • 左上限代表所有的条件;
    • 左下限代表可能的结果;
    • 右上限代表每一种条件的取值(用Y和N来表示);
    • 右下限用X表示所对应的条件组合所产生的结果。
  2. 判定树 判定树(Decision Tree)也称为决策树,是用来描述在一组不同的条件下,决策的行动是根据不同条件及其取值来选择的处理过程。业务规则的描述通常可以使用判定树这一过程描述工具。

  3. 结构化语言 若逻辑关系比较简单,可以用结构化自然语言来描述。

4.应用中注意的问题
  1. 模型平衡问题

    • DFD图与数据字典的一致;
    • 底层加工的处理逻辑描述,与数据字典一致;
  2. 信息的复杂性控制问题

    • 上层数据流可以打包;
    • 下层模块个数:7+-2(6);
    • 每个加工的数据流不能太多:增加层次;
5.需求验证
  1. 验证:必要性、无歧义性、可测性、可跟踪性、可测量性
  2. 需求中发现的错误类型
    • 不正确的事实:40%;
    • 遗漏:31%;
    • 不一致:13%;
    • 歧义性:5%;
    • 错放:2%;
    • 其他:9%
发现错误的方法
  • 审查:65%
  • 单元测试:10%
  • 评估:10%
  • 集成:5%
  • 其他:10%

第二节 结构化设计

任务
  1. 定义满足需求所需要的结构
  2. 确定“怎么做”的问题
  3. 划分为:总体设计(以系统为对象);详细设计(以模块为对象)
总体设计
  1. 总体设计的任务:把系统的功能需求分配到一个特定的软件系统结构中。
  2. 引入了两个概念:
    • 模块:软件中具有特定标识的独立成分;
    • 模块调用:模块之间的一种使用关系;
如何表达模块和模块调用
  1. Yourdon提出的模块结构图
  2. 层次图
  3. 美国IBM公司提出的HIPO图(H:层次图,IPO:输入/处理/输出图,每一个模块都有编号)
总体设计的步骤

将DFD图映射为设计层面的模块及模块调用。 1)将DFD图转换为初始的模块结构图; 2)基于“高内聚、低耦合”的软件设计原理,通过模块化,将初始的模块结构图转化为最终的模块结构图。

两种映射方法
  1. 变换设计 基于变换的数据流程图是一个线性的顺序结构,由输入(I)、输出(O)和变换中心(P)三部分组成。 变换型数据流程图时一个线性的顺序结构,由输入臂、输出臂和变换中心三部分组成。其中变换中心使系统数据发生本质的变化。输入臂将物理输入变换成逻辑输入,而输出臂则将逻辑输出变换成物理输出。 如果待分解的模块是一个数据凝聚的模块,称该模块为以转换为中心的模块。可以把它分为输入、处理、输出三大模块。

  2. 事务设计 基于事务的数据流程图中有一个事务处理中心,它将输入分为许多相互平行的加工路径,然后根据输入的属性,选择某一加工路径。 如果模块为逻辑凝聚的模块,可以将它分解为一个检查业务类型的模块和一个调度模块,根据不同的业务类型,调度模块调用不同的下层模块。

  3. 模块化及其启发式规则 1)模块 执行一个特殊任务的一个过程以及相关的数据结构。模块通常由两部分组成:模块接口和模块体。 2)模块化的两个问题

    1. 如何将系统分解成软件模块
    • 分而治之和抽象
    • 自顶向下,逐步求精
    • 形成模块层次结构
    1. 如何设计模块
  4. 模块化 把一个待开发的软件分解成若干个简单的、具有高内聚低耦合的模块,这一过程称为模块化。

1)模块耦合 耦合是对两个模块之间相互依赖程度的一种度量。模块间的依赖程度越大,则其耦合程度也就越大;反之,模块间的依赖程度越小,则其耦合程度也就越小。 模块间耦合类型

  • 内容耦合:一个模块直接修改或操作另一模块数据;
  • 公共耦合:两个模块共同引用一个全局数据项;
  • 控制耦合:一个模块向另一模块传递控制信号;
  • 标记耦合:一个模块向两个模块传递一个公共参数;
  • 数据耦合:模块之间通过参数来传递数据;(最优)

2)模块内聚 是指一个模块内部各成分之间相互关联程度的度量。也就是说,内聚是对模块内各处理动作组合程度的一种度量。很显然,一个模块的内聚越大越好。 内聚的类型

  • 偶然内聚:模块的各成分没有任何关系;
  • 逻辑内聚:逻辑上相关的处理放在一起;
  • 时间内聚:模块内的功能在同一时间完成;
  • 过程内聚:模块内的处理以特定的次序执行;
  • 通信内聚:操作同一数据集;
  • 顺序内聚:一个成分的输出作为另一成分的输入;
  • 功能内聚:模块的所有成分完成单一的功能;(最优)

3)启发式规则 高内聚低耦合

  1. 改进软件结构,提高软件独特性。模块分解
  2. 模块规模适中;
  3. 力求深度、宽度、扇出、扇入适中。
    • 深度:表示其控制的层数。
    • 宽度:同一层次上模块总数的最大值。
    • 扇出:一个模块直接控制的下级模块的数目;
    • 扇入:有多少个上级模块直接调用它。
  4. 尽量使模块的作用域在其控制域内。
    • 模块的控制域:这个模块本身以及所有直接或间接从属他的模块的集合。
    • 模块的作用域:受该模块内一个判断所影响的所有模块的集合。
  5. 尽力降低模块接口的复杂度
  6. 力求模块功能可以预测
详细设计

具体描述模块结构图中的每一模块,即给出实现模块功能的实施机制,包括一组例程和数据结构。 详细设计的目标:将总体设计阶段产生的系统高层结构映射为以相关术语表达的低层结构,也是系统的最终结构。

结构化程序设计方法

是一种基于结构的编程方法,即采用顺序结构、选择结构和重复结构进行编程,其中每一结构只允许一个入口和一个出口。 结构化程序设计的本质是:使程序的控制流程线性化,实现程序动态执行顺序符合静态书写的结构,提高程序的可读性。

  1. 顺序结构
  2. 选择结构
  3. 多分支结构
  4. 循环结构
详细设计工具
  1. 程序流程图 程序流程图:程序流程图又称为程序框图,它是历史最悠久使用最广泛的描述过程设计的方法,然而它是用得最混乱的一种方法。

  2. 盒图(N-S图) 出于要有一种不允许违背结构程序设计精神的图形工具的考虑,Nassi和Shneiderman提出了盒图,又称为N-S图。

  3. PAD图 PAD是问题分析图(Problem Analysis Diagram)的英文缩写,自1973年由日本日立公司发明以后,已得到一定程度的推广。它用二维树形结构的图来表示程序的控制流,将这种图翻译成程序代码比较容易。

  4. 类程序设计语言PDL PDL也称为伪码,它是用正文形式表示数据和处理过程的设计工具。 PDL具有严格的关键字外部语法,用于定义控制结构和数据结构; 一般说来PDL是一种混杂语言,它使用一种语言(通常是某种自然语言)的词汇,同时却使用另一种语言(某种结构化的程序设计语言)的语法。

设计规约

完整准确地描述满足需求规约所要求的所有功能模块,以及伴随功能模块而出现的非功能机制。设计规约包括概要设计规约和详细设计规约。

  1. 概要设计规约 指明高层软件体系结构

    • 系统环境
    • 软件模块的结构
    • 模块描述
    • 文件结构和全局数据文件的逻辑结构
    • 测试需求
  2. 详细设计规约 详细设计规约主要作为软件设计人员与程序员之间交流的媒体。

    • 各处理过程的算法
    • 算法所涉及的全部数据结构的描述