软件工程 Software Engineering 第二章 软件质量评价 武汉大学 计算机学院 软件工程课程组
思考? 什么是好的软件? 软件质量好坏如何评价?
第二章 软件质量评价 什么是好的软件?有何特点? 软件评价的标准如何? 什么是软件结构?什么是良软件结构? 什么是模块化? 第二章 软件质量评价 什么是好的软件?有何特点? 软件评价的标准如何? 什么是软件结构?什么是良软件结构? 什么是模块化? 模块设计时应遵循的标准是什么?
一、软件质量评价标准 有效可靠 结构清晰 用户角度:达到需求、界面友好、简单易学 开发人员角度:良结构、易测试、易维护、可移植 … 文档齐全
二、软件结构 软件的各个组成部分之间的关系 问题P 同一个问题P的三种不同的软件结构
基本概念 块:可以独立命名和编址的单元 扇出:直接由一个块所控制的块数 扇入:直接调用它的上级块数目 深度:控制的总层数 宽度:跨度最宽层的跨度数 M M1 M2 M3 N1 N2 N3 N4 N31 N32 软件结构
1. 良软件结构 具有层次性,无回路块调用的软件结构。 树型 半序型 … 线性型
非良结构的调整 模块内部 复杂性增加了 网络结构 A B AB 合并循环节点 良结构
2. 模块化(modularity) 模块(module):又称构件,是能够单独命名并独立地完成一定功能的程序语句的集合。 模块化 把程序划分成独立命名且可独立访问的模块,每个模块完成一个子功能,把这些模块集成起来构成一个整体,可以完成指定的功能满足用户的需求。 “模块化”有助于复杂问题的求解
如果把软件无限细分, 会出现什么样的情况? 模块化的依据 c(x):问题 x 的复杂程度 E(x):解决问题 x 需要的工作量(时间) 对于两个问题P1和P2 if C(P1) > C(P2) then E(P1) > E(P2) 根据人们求解问题的经验,有规律:C(P1+P2) > C(P1)+C(P2) 则有 E(P1+P2) > E(P1)+E(P2) 即“分而治之”有助于复杂问题的求解。 如果把软件无限细分, 会出现什么样的情况?
块的划分与总工作量之间的关系 模块划分的合理性。模块两个定性的标准:内聚和耦合。 接口成本 总成本 块成本 成本 (工作量) 模块数 M 最小成本区域 总成本 块成本 成本 (工作量) 模块数 M 模块划分的合理性。模块两个定性的标准:内聚和耦合。
模块的重要特征 抽象(abstraction) 信息隐藏(information hiding) 细节隐藏 可理解性 修改副作用小 我们在考虑问题时,集中考虑和当前问题有关的方面,而忽略和当前问题无关的方面,这就是抽象。或者说抽象就是抽出事物的本质特性而暂时不考虑它们的细节。 在对软件系统进行模块设计时,可以有不同的抽象层次。 忽略细节,分层理解问题,自顶向下层层细化 信息隐藏(information hiding) 细节隐藏 可理解性 修改副作用小 错误副作用小
模块化的抽象特征 抽象层次I 用问题环境的术语来描述这个软件 例:开发一个CAD软件,实现一个二维绘图系统的全部功能,供低级计算机辅助设计使用。 抽象层次I 用问题环境的术语来描述这个软件 该软件包括一个计算机绘图界面,向绘图员显示图形,以及一个数字化仪界面,用以代替绘图板和丁字尺。所有直线、折线、矩形、圆及曲线的描画、所有的几何计算、所有的剖面图和辅助视图都可以用这个CAD软件实现……
模块化的抽象特征 抽象层次II 任务需求的描述,列出“What”而不是“How” CAD SOFTWARE TASKS: user interaction task; 2-D drawing creation task; graphics display task; drawing file management task; END
模块化的抽象特征 抽象层次III 程序过程表示 (以2-D绘图生成任务为例) PROCEDURE 2-D drawing creation REPEAT UNTILE (drawing creation task terminates) DO WHILE (digitizer interaction occurs) Digitizer interface task; DETERMINE drawing request CASE Line: line drawing task; Rectangle: rectangle drawing task; Circle: circle drawing task; …… END; DO WHILE (keyboard interaction occurs) keyboard interaction task; PROCESS analysis/computation CASE View: auxiliary view task; Section: cross sectioning task; END REPETITION; END PROCEDURE.
3. 模块独立性(Module independence) 好设计的关键: 每个模块完成一个相对独立的子功能,并且与其它模块间的接口简单。 独立性的度量(Yourdon & Constantine,1978) 耦合(Coupling) — 块间联系 内聚(Cohesion) — 块内联系
(1)耦合(Coupling) 对一个软件结构内不同模块之间互连程度的度量 Highly coupled Great deal of dependence Independent Highly coupled Loosely coupled Uncoupled Goal: as loose as possible = as independent as possible
零耦合(uncoupling) 彼此完全独立,这意味着模块间无任何连接,耦合程度最低 Uncoupled A B
数据耦合(Data Coupling) The most desirable 一个模块访问另一个模块时,彼此间通过参数交换信息,而且交换的信息仅仅是数据 A B Data The most desirable
控制耦合(Control Coupling) 指一个模块调用另一个模块时,传递的信息中有控制信息(尽管有时这种控制信息以数据的形式出现) A B Flag F2 Fn F1 …… 控制耦合增加了理解与编程及修改的复杂性。
公共环境耦合(Common Coupling) 两个或多个模块通过一个公共数据环境相互作用 Global : V1 V2 A: ………… A1=V1+V2 B: V1=B1 Global : V1 V2 A: ………… V1++ B: V2=B1+V1 问题:复杂程度随耦合模块的个数增加而增加 公共部分的数据存取无法控制 公共部分的改动将影响所有调用它的模块,可维护性差
内容耦合(Content Coupling) 一个模块访问另一个模块的内部数据 一个模块不通过正常入口而转到另一个模块的内部 两个模块有一部分程序代码重叠(只可能出现在汇编程序中) 一个模块有多个入口 The least desirable
内容耦合 …… A B C D A: ………… goto C1 C: C1: 例1. A访问C的内部数据或不通过正常入口而转入C的内部。
内容耦合 例2. 部分代码重叠 (常出现在汇 编程序中) 例3. 一个模块有 多 个入口(功能) A B A: ……………… 例2. 部分代码重叠 (常出现在汇 编程序中) B A 例3. 一个模块有 多 个入口(功能) A: ……………… entry 1: entry 2:
耦合度与软件结构 原则:尽量使用数据耦合,少用控制耦合,限制公共环境耦合的范围,完全不用内容耦合。 类 型 耦合度 模块独立性 软件结构 类 型 耦合度 模块独立性 软件结构 零耦合 低 高 强 弱 好 差 数据耦合 控制耦合 公共环境耦合 内容耦合 原则:尽量使用数据耦合,少用控制耦合,限制公共环境耦合的范围,完全不用内容耦合。
思考题 已知模块A、E和F更新同一个数据库, 请确定模块之间的耦合类型。 模块接口描述 A B D C F E 1 3 2 4 5 6 模块互连图 编号 输入 输出 1 飞机类型 状态标志 2 飞机零件清单 3 功能代码 4 5 零件编号 零件制造商 6 零件名称 已知模块A、E和F更新同一个数据库, 请确定模块之间的耦合类型。
(2)内聚(Cohesion) 一个模块内各个元素彼此结合的紧密程度 理想内聚的模块只做一件事情 模块内的高内聚往往意味着模块间的松耦合 内聚更重要! Goal: as cohesive as possible!
偶然内聚(Coincidental cohesion) Unrelated functions, processes, or data are found in the same module (for convenience) A B A B C 语句相同
逻辑内聚(Logical Cohesion) Logically related functions or data are placed in the same module A: Read inputs from disk from tape from ……
逻辑内聚 X Y Z A B C X Y Z ABC S
时间内聚(Temporal cohesion) The functions are related only by the timing involved initial x Initial y 这种模块在20世纪80年代的应用程序中使用较多。没有任何复用价值。
过程内聚(Procedural cohesion) Functions are grouped together in a module to ensure a certain order of performance enter data check data manipulate data
通信内聚(Communicational cohesion) All the functions in a module operate on or produce the same data set X 从文件file读出数据 由数据产生日报表 由数据产生单项产品报表
顺序内聚(Sequential cohesion) The output from one part of a module is the input to the next part X 输入系数 求根 打印方程的根
功能内聚(Functional cohesion) Every processing element is essential to the performance of a single function X 报表打印
内聚度与软件结构 设计时力争做到高内聚 !不要低内聚! 软件结构 模块独立性 内聚度 内聚 评分 差 好 弱 强 低 偶然内聚 0分 逻辑内聚 1分 时间内聚 3分 中 过程内聚 5分 通信内聚 7分 高 顺序内聚 9分 功能内聚 10分 设计时力争做到高内聚 !不要低内聚!
三、软件度量 软件度量的根本目的是为了管理的需要。利用度量来改进软件过程。 度量(metrics) 测量(measure) 估算(estimation)
软件度量 软件复杂性度量 规模 文本复杂性 控制结构的复杂性 软件可靠性度量 系统故障率 软件修复与软件有效性 软件可靠性估算
1. 软件复杂性度量 规模:程序代码的规模→软件复杂度 文本复杂性 控制结构的复杂性
(1)规模度量(Size-Oriented Metrics) 代码行(Lines of code,LOC)度量 LOC 乐观值a 一般值m 悲观值b LOC的期望值
代码行(Lines of code,LOC) 生产率(LOC per person-month)= 代码行数/工作量 Pl = L / E 每行代码的平均成本($ per LOC)=总成本/代码行数 Cl = S / L 代码出错率(Errors per kLOC)=总错误数/代码行数 EQRl = Ne / L
某软件项目记录 Pl = 12.1 kLOC / 24 PM = 504 LOC/PM 工作量 PM 成本 ($) 代码行 kLOC 文档页数 Pd 错误数 Ne 人数 M aaa-01 24 168000 12.1 365 29 3 ccc-04 62 440000 27.2 1224 86 5 fff-03 43 314000 20.2 1050 64 6 Pl = 12.1 kLOC / 24 PM = 504 LOC/PM Cl = $168000 / 12.1 kLOC = $13.88/LOC EQRl = 29个 / 12.1 Kloc = 2.4个/kLOC
代码行数估算软件规模的特点 优点:简单易行 缺点: 软件≠程序 不能刻画算法的难易程度 开发前或初期估算困难 依赖于语言 只适用于过程式语言,不适用于4GL
N1:程序中操作符个数 n1:程序中不同操作符个数 N2:程序中操作数个数 n2:程序中不同操作数个数 (2)文本复杂性度量 程序语言符号长度 N = N1 + N2 N1:程序中操作符个数 n1:程序中不同操作符个数 N2:程序中操作数个数 n2:程序中不同操作数个数 估算公式 N = n1log2n1 + n2log2n2 程序量 V = N log2(n1 + n2)
(3)控制结构的复杂性度量 1976,T. J. McCabe 基于程序拓扑结构的软件复杂性度量模型 巡回秩数V(G) V(G) = e – n + 2 = 边数 – 结点数 + 2 可以证明: V(G) = 有界或无界的封闭区域个数
程序控制结构的复杂性 R1 R2 选择结构 R1 顺序结构 R1 R2 a b c d e R3 R1 R2 While结构 R1 R2 Repeat结构
2. 软件可靠性度量 软件的可靠性 在某个给定时间间隔内,程序按照规格说明成功运行的概率
软件修复与软件有效性 有效性函数A(t) 可靠性函数R(t) A = MTTF / (MTTF + MTTR) 系统在t时刻正常运行的概率
软件可靠性估算 错误植入模型 N:池塘中的鱼尾数 Nt:植入的带标记的鱼尾数 n:捞出的鱼尾数 nt:捞出的带标记的鱼数
小 结 软件评价标准 软件结构 模块化 模块独立性 软件度量
思考题 你认为评价软件好坏有哪些标准? 在设计软件结构时应遵循哪些原则? 某软件项目如果采用四代语言开发,LOC度量还有意义吗?为什么? 一个程序能既正确又不可靠吗?试说明理由。