1、软件设计-实现-测试-维护,概要设计 详细设计 编码及调试 测试 维护,概要设计,概要设计阶段的步骤、方法和图形工具。 概要设计步骤 软件结构设计的基本原理 软件结构设计的图形工具HIPO图结构图 概要设计方法 概要设计文档与复审面向对象的概要设计(RUP),概要设计步骤,概要设计的基本任务 1. 审查可行性研究报告和需求分析规格说明书。 2. 确定模块结构、数据文件结构、系统接口设计和测试方案策略。 3. 编写概要设计说明书、用户手册和测试计划。 4. 复审。,概要设计步骤,概要设计的基本步骤: 软件结构设计 数据结构设计及数据库设计 系统接口设计 测试方案设计 复审,软件结构设计 1. 设
2、计供选择的方案 2. 推荐最佳实现方案 3. 设计软件结构 数据结构设计及数据库设计 数据结构设计 数据库设计,概要设计步骤,概要设计步骤,系统接口设计 系统接口包括内部接口、外部接口和用户接口。 数据流图和控制情况是接口设计的基础。 设计测试方案 在概要设计阶段,测试方案主要根据系统功能来设计,称为黑盒法测试。,软件结构设计的基本原理,模块与模块化 模块的耦合和内聚 软件结构设计优化准则,软件结构设计的基本原理,模块与模块化 1、模块 模块(module)是能够单独命名,能独立地完成一定功能, 由边界元素限定的程序元素的序列。 模块的基本属性:名称 、接口、功能、逻辑、状态。,模块与模块化,
3、2、模块化(Modularization)是把系统分割成能完成独立功能的模块,这些模块集成起来构成一个整体,可以完成指定功能,满足用户需求。,模块与模块化,模块化的目的是将系统“分而治之”,模块化能够降低问题的复杂性,使软件结构清晰,易阅读、易理解,易于测试和调试,因而也有助于提高软件的可靠性。,模块与模块化,规律一:如果问题P1的复杂性大于问题P2 ,则解决问题P1需要的工作量大于解决问题P2需要的工作量。 C(P1)C(P2)显然 E(P1)E(P2)这个不等式导致“各个击破”的结论把复杂的问题分解成许多容易解决的小问题,原来的问题也就容易解决了。这就是模块化的根据。,模块与模块化,规律二
4、:如果一个问题Q分别由P1和P2组成而成,那么它的复杂程度大于分别考虑每个问题时的复杂程度之和。由此可以得出,解决问题Q需要的工作量大于分别解决问题P1和P2需要的工作量之和。C(P1 + P2)C(P1)+C(P2)也就是说,如果一个问题由和两个问题组合而成,那么它的复杂程序大于分别考虑每个问题时的复杂程度之和。综上所述,得到下面的不等式E(P1 + P2)E(P1)+E(P2),模块与模块化,当模块数目增加时每个模块的规模将减小,开发单个模块需要的成本(工作量)确实减少了;但是,随着模块数目增加,设计模块间接口所需要的工作量也将增加。根据这两个因素,得出下图中的总成本曲线。每个程序都相应地
5、有一个最适当的模块数目M,使得系统的开发成本最小。,模块与模块化,模块与模块化,4、 模块分割方法(1)抽象与详细化(2)根据功能来划分模块 横向分割 纵向分割 先确定中心控制模块,由控制模块指示从属模块,逐次进行分解。,软件结构设计的基本原理,模块化 抽象 模块独立性 信息隐藏,软件结构设计的基本原理,抽象与细化 抽象是一种思考方式,它集中注意事物某个一般性级别上的问题,避开不必要的低层细节 软件开发的过程就是一个从抽象到具体的过程: 需求设计编码 过程抽象和数据抽象,软件结构设计的基本原理,细化 是与抽象互补的一个概念,主要思想是将某个宏观功能不断分解,逐步确立过程细节,直至用程序设计语言
6、描述的算法实现为止。,软件结构设计的基本原理,信息隐藏和局部化 信息隐藏是指在设计和确定模块时,使一个模块内包含的信息(过程和数据)对于不需要这些信息的模块来说,是不能访问的。也就是说,模块中所包括的信息不允许其他不需要这些信息的模块调用。,软件结构设计的基本原理,局部化是指把一些关系密切的软件元素物理的方的彼此靠近,有助于实现信息隐藏。 实际上,隐藏的不是有关模块的一切信息,而是模块的实现细节,因此,有称为“细节隐藏”。 在面向对象方法中,对象的封装性很自然地支持了信息隐藏的思想。,软件结构设计的基本原理,模块独立 模块独立性是模块化、抽象和信息隐藏的直接产物,其基本含义是每一个模块只具有一
7、个简单的接口。 方法:开发具有独立功能而且和其他模块之间没有过多的相互作用的模块。,软件结构设计的基本原理,理由 第一,有效的模块化(即具有独立的模块)的软件比较容易开发出来。 第二,独立的模块比较容易测试和维护。,软件结构设计的基本原理,模块独立性主要有两个定性的度量标准: 耦合性 用于描述模块之间联系的紧密程度。 内聚性 用于描述模块内部联系的紧密程度。模块独立性比较强的模块应该是具有高内聚性和的低耦合度。,模块的耦合和内聚,1. 模块的耦合 软件结构中模块之间互相依赖的程度用耦合来度量。 数据耦合 控制耦合 公共环境耦合 内容耦合 总之,应: 在尽量使用数据耦合, 少用控制耦合。 用参数
8、传递信息,不采用内容耦合, 尽量控制公共环境耦合。,2. 模块的内聚,一个模块内各个元素彼此结合的紧密程度用内聚来度量。 ()偶然内聚 ()逻辑内聚 ()时间内聚 ()通信内聚 ()顺序内聚 ()功能内聚内聚按紧密程度从低到高排列: 偶然内聚、逻辑内聚、时间内聚、通信内聚、功能内聚。,软件结构设计优化准则,1. 提高模块独立性 2. 模块接口的准则模块的接口要简单、清晰,含义明确,便于理解,易于实现、测试与维护。 3. 模块的作用范围应在控制范围之内 4. 模块的深度、宽度、扇出和扇入应适当 5. 模块的大小应适中,软件结构设计的图形工具,4.3.1 层次图(或HIPO图),(2) 层次图和H
9、IPO图,改进的IPO图,层次图例,HIPO中的层次图,结构图,1. 结构图的符号 (1)方框代表模块,框内注明模块的名字和主要功能。 (2)方框之间的大箭头或直线表示模块的调用关系。 (3)带注释的小箭头表示模块调用时传递的信息及其传递方向。 尾部加空心圆的小箭头表示传递数据信息。 尾部加实心圆的小箭头表示传递控制信息。 (4)选择结构 (5)循环结构,模块 H 循环调用模块 A,B,C,见图4.5(b)。,例:画出打印报告的软件结构图,调用次序为上层调用下层; 同层按照数据传递关系确定;一般从左到右执行。执行过程即按照数据流向进行。,报 告,计 算,获得编辑,确认数据,读入,编辑,打印报告
10、头,打印报告尾,打印,输入 EOF,输入,已编辑,已编辑,已编辑,已确认,已确认 数据,已确认 数据,计算结果,结果,日期,总结果,行,行,行,打印报告,予以确认,2. 结构图的绘制,【例4-6】学生成绩管理系统的结构图,概要设计方法,结构化方法 结构化方法又称面向数据流设计方法(Structured Design,SD)。 设计步骤是先根据系统数据流图建立系统逻辑模型,再进行结构设计。 1. 建立系统逻辑模型 ()变换型数据流 ()事务型数据流 【例4.7】学生成绩管理系统系统属于变换型数据流。 【例4.8】工资管理系统属于事务型数据流。 【例4.9】医疗费管理系统中事务型、变换型两种数据流
11、同时存在 2. 完成软件结构设计,二、典型的系统结构,变换型系统结构图 通过变换分析技术,将中心变换型的DFD图转换而得的SC图,称为变换型系统结构图。 事务型系统结构图 通过事务分析技术,将事务处理型的DFD图转换为的SC图,称为事务型的系统结构图。, 确定主加工及逻辑输入/输出主加工 描述了系统的主要功能、特征。其特点是:输入/输出数据流较多,往往主加工不止一个。逻辑输入/输出 是指输入/输出主加工的数据流。输入流 是把物理输入转换为逻辑输入的数据流。 输出流 是将逻辑输出转换为物理输出的数据流。,输 入 流,转换流,输出 流,输 入 流,转换流,输出 流, 进行一级分解,设计上层模块为每
12、个输入设计一个输入模块,为每个输出设计一个输出模块,同时为每个主加工设计一个处理模块。,M,CI,CT,CO,C,C,D,D,CI,CT,CO,变换分析技术,变换分析技术, 进行二级分解,设计中下层模块这一步的工作是自顶向下,逐步细化,为第一层的每一个输入模块、输出模块、处理模块设计它们的从属模块,设计下层模块的顺序一般从设计输入模块的下层开始。,M,CI,CT,CO,处理C,取B,转换B,转换D,送E, 进一步细化,取A,转换A,转换E,送F,变换分析技术,事务分析技术, 确定流界;首先从数据流图中找出事务流、事务处理中心和事务路径。,对 应 模 块 图,事务控制,接受事务,发送事务,P1,
13、P2,P3,进行一级分析,设计上层模块;对事务中心应设计“事物控制”模块;对事物流应设计“接受事物”模块;对事务路径,应设计“发送控制”模块。,进行二级分解,设计中下层模块;接受分支,用类似于转换处理型数据流图中对输入数据流的方法设计中下层。对于发送分支,在发送控制模块下为每条事务路径设计一个事务处理模块,这一层称为事务层。,事务分析技术,面向数据结构设计方法,Jackson 把数据结构(或程序结构)分为三种基本类型 :(a)顺序 (b)选择 (c) 循环,类图和对象图,6.1 类图的概念 6.2 类图建模技术 6.3 对象图 6.4 对象图建模技术 6.5 实例图书馆管理系统的类图,类图的概
14、念,描述类、接口、协作及它们之间关系的图。 显示系统中各个类的静态结构。,概述,类图的元素: 类(Class) 接口(Interface) 协作(Collaboration) 依赖关系(Dependency) 泛化关系(Generalization) 关联关系(Association) 实现关系(Realization),类,面向对象系统组织结构的核心。 对一组具有相同属性、操作、关系和语义的对象的抽象。 包括名称部分(Name)、属性部分(Attribute)和操作部分(Operation)。,类,1 名称 2 属性 3 操作 4 职责 5 约束 6 注释,名称,应该来自系统的问题域。 应该
15、是一个名词,且不应该有前缀或后缀。 分为简单名称和路径名称。,属性,描述了类在软件系统中代表的事物(即对象)所具备的特性。 类可以有任意数目的属性,也可以没有属性。 在UML中,类属性的语法为:,属性,1. 可见性 2. 属性名 3. 类型 4. 初始值 5. 属性字符串,(1) 可见性,类型: 公有(Public) “” 私有(Private)“” 受保护(Protected)“”,(2) 属性名,每个属性都必须有一个名字以区别于类中的其他属性。 属性名由描述所属类的特性的名词或名词短语组成。 单字属性名小写,如果属性名包含了多个单词,这些单词要合并,且除了第一个单词外其余单词的首字母要大写
16、。,(3) 类型,简单类型: 整型 布尔型 实型 枚举类型 系统中的其他类,(4) 初始值,目的: 保护系统的完整性,防止漏掉取值或被非法的值破坏系统的完整性。 为用户提供易用性。,(5) 属性字符串,指定关于属性的其他信息。 任何希望添加在属性定义字符串值但又没有合适地方可以加入的规则,都可以放在属性字符串里。,操作,对类的对象所能做的事务的抽象。 一个类可以有任意数量的操作或者根本没有操作。 返回类型、名称和参数一起被称为操作签名。 在UML中,类操作的语法为:,操作,1. 可见性 2. 操作名 3. 参数表 4. 返回类型 5. 属性字符串,职责,类或其他元素的契约或义务。 自由形式的文
17、本。 非形式化的方法。,约束,指定了类所要满足的一个或多个规则。 形式化的方法。,注释,注释可以包含图形也可以包含文本。,接口,在没有给出对象的实现和状态的情况下对对象行为的描述。 包含操作但不包含属性。 没有对外界可见的关联。 一个类可以实现一个或多个接口。,接口,接口类:,类之间的关系,1 依赖关系 2 泛化关系 3 关联关系 4 实现关系,依赖关系,表示两个或多个模型元素之间语义上的关系。 客户以某种形式依赖于提供者。 ,关联、实现和泛化都是依赖关系。,依赖关系,1. 使用依赖(Usage) 2. 抽象依赖(Abstraction) 3. 授权依赖(Permission) 4. 绑定依赖
18、(Binding),泛化关系,存在于一般元素和特殊元素间的分类关系。 可以用于类、用例以及其他模型元素。 描述了一种“is a kind of” 的关系。,泛化关系,泛化主要用途: 多态 继承 单继承 多重继承,关联关系,一种结构关系。 指明事物的对象之间的联系。,关联关系,1. 名称(Name) 2. 角色(Role) 3. 多重性(Multiplicity) 4. 聚合关系(Aggregation) 5. 组合关系(Composition) 6. 导航性(Navigation),实现关系,规格说明和其实现之间的关系。 客户必须至少支持提供者的所有操作。 泛化和实现都可以将一般描述与具体描述
19、联系起来: 泛化将同一语义层上的元素连接起来,并且通常在同一模型内。 实现将不同语义层内的元素连接起来,并且通常建立在不同的模型内。,类图建模技术,6.2.1 对简单协作建模 6.2.2 对逻辑数据库模式建模 6.2.3 正向工程和逆向工程,对简单协作建模,识别要建模的机制。 对每种机制,识别参与协作的类、接口和其他协作,并识别这些事物之间的关系。 用协作的脚本检测事物。 把元素和它们的内容聚合在一起。,对逻辑数据库模式建模,在模型中识别的类,其状态必须超过其应用系统的生命周期。 创建包含这些类的类图,并把它们标记为永久的。 展开这些类的结构性细节,并注重于关联和构造类的基数。 观察系统中的公
20、共模式,必要时可以创建简化逻辑结构的中间抽象。 考虑这些类的行为,扩展对数据存储和数据完整性来说重要的操作。 如果有可能,用工具把逻辑设计转换成物理设计。,正向工程和逆向工程,正向工程 逆向工程,对象图,描述参与一个交互的各个对象在交互过程中某一时刻的状态。 可以被看作是类图在某一时刻的实例。,类图和对象图的区别,对象图建模技术,识别将要使用的建模机制。 对于各种机制,识别参与协作的类、接口和其他元素,同时识别这些事物之间的关系。 考虑贯穿这个机制的脚本,冻结某一时刻的脚本,并且汇报每个参与这个机制的对象。 按照需要显露出每个这样的对象的状态和属性值,以便理解脚本。 显露出这些对象之间的链,以
21、描述对象之间关联的实例。,实例图书馆管理系统的类图,6.5.1 使用Rational Rose绘制类图的步骤 6.5.2 图书馆管理系统的类图,使用Rational Rose绘制类图的步骤,1. 创建类图 2. 加入类 3. 增加类的属性 4. 增加类的方法,图书馆管理系统的类图,7个类: Item Title Loan Reservation Borrower Administrator Librarian,图书馆管理系统的类图,概要设计文档与复审,4.5.1 概要设计说明书 4.5.2 概要设计复审 4.5.3 数据库设计说明书,小结,概要设计的基本任务是确定模块结构、数据文件结构、系统接
22、口设计和测试方案策略,编写概要设计说明书、用户手册和测试计划。 概要设计要经过严格的评审。 软件设计的基本原理是抽象、逐步求精、模块化、信息隐蔽。 模块设计的优化准则 软件结构设计的图形工具有层次图、HIPO图和结构图。 传统软件工程方法在概要设计阶段常用面向数据流设计方法或面向数据结构设计方法。,详细设计,本章主要内容: 过程设计:流程图、N_S图、PAD图、判定表、判定树、过程设计语言(PDL)等。 用户界面设计 数据代码设计的原则、种类、方法 数据输入、输出设计 数据安全设计 详细设计文档与复审 本章重点: 结构化设计 过程设计工具 用户界面设计,详细设计的主要任务: 过程设计和系统界面
23、设计,结构化设计建立在自顶向下设计、逐步求精方法和数据流分析等原则基础上。 结构化设计只用三种基本控制结构:顺序结构、条件结构和循环结构。 过程设计的任务是设计软件结构中每个模块功能的实现算法。系统界面设计要完成系统外部接口、系统内部模块接口和用户界面的设计。 用户界面设计是软件与使用它的人之间的通信接口的设计。,过程设计,过程设计就是用顺序、选择和循环三种结构的有限次组合或嵌套,描述模块功能的实现算法。 过程设计阶段的工具:流程图、N_S图、问题分析图(PAD图)、 判定表、判定树、过程设计语言(PDL)等。 流程图 1. 流程图的分类 (1)数据流程图 (2)程序流程图 (3)系统流程图
24、(4)程序网络图 (5)系统资源图,2. 流程图符号,3 流程图使用约定,4. 流程图的三种基本结构: 顺序、选择、循环。,盒图 盒图是Nassi和Shneiderman提出的,又称N_S图。 1. 盒图的符号,a,b,条 件 1,T,F,Case Xi, i=2,3,4,X2,X3,X4,当条件3成立,条 件 2,直到条件4成立,直 到 条 件 成立,c,d,e,f,g,h,i,j,顺序结构,选择结构,多分支选择结构,先判定型循环结构,后判定型循环结构,F,T,T,F,N-S图举例,NS图举例,【例.1】将下述含有GOTO语句的用程序流程图,改为N_S图。,【例.2】学生成绩管理系统的 N-
25、S 图。,(2) 盒图(NS图),与程序流程图相比较,盒图具有如下明显的优点: l 在盒图中不能任意转移控制。l 特定控制逻辑的作用范围明确,可以从盒图上一目了然。 l 很容易确定局部和全程数据的作用域。l 很容易表现嵌套关系,也容易表示模块的层次结构。 l 所有的程序结构均用方框表示。因此程序的结构非常清晰。,(2) 盒图(NS图),l 程序只有一个入口、一个出口,完全能够满足单人口单出口的结构化程序设计要求。l 盒图形象直观,具有良好的可视性。循环的范围、条件语句的控制范围等都是一目了然的。l 盒图简单,易学易用。主要缺点是:当程序内嵌套的层数增多时,内层方框会越来越小,一方面会增加画图难
26、度,另一方面会影响图形的清晰度。,PAD 图 基本符号,【例.3】学生成绩管理系统的 PAD 图,判定表,判定表的组成左上部列出所有条件。 左下部列出所有可能做的工作。 右上部每一列表示各种条件的一种可能组合,所有列表示条件组合的全部可能情况。 右下部的每一列是和每一种条件组合所对应的应做的工作。,判定表,判定表中的符号右上部用“T”表示条件成立,用“”表示条件不成立,空白表示条件成立与否不影响。 右下部画“X”表示做该行左边列出的那项工作,空白表示不做该项工作。,例.4 用判定表表示旅游票价的优惠规定。,某旅行社根据旅游淡季、旺季及是否团体订票,确定旅游票价的折扣率。具体规定如下:人数在20
27、人以上的属团体,20人以下的是散客。每年的4-5月、7-8月、10月为旅游旺季,其余为旅游淡季。旅游旺季,团体票优惠5,散客不优惠。旅游淡季,团体票优惠30,散客优惠20。用判定表表示旅游订票的优惠规定。,例.5 用判定树表示旅游价格优惠规定。,某旅行社根据旅游淡季、旺季及是否团体订票,确定旅游票价的折扣率。具体规定如下:人数在20人以上的属团体,20人以下的是散客。每年的4-5月、7-8月、10月为旅游旺季,其余为旅游淡季。旅游旺季,团体票优惠5,散客不优惠。旅游淡季,团体票优惠30,散客优惠20。用判定表表示旅游订票的优惠规定。,过程设计语言,过程设计语言(Program Design L
28、anguage,简称 PDL),也称伪码,是一种混杂语言,说明某种结构化的程序设计语言的语法形式。 用PDL表示的程序结构: 1 顺序结构 处理1处理2处理3 选择结构 IF-THEN-ELSE结构:IF 条件处理1ELSE 处理2 ENDIF IF-THEN结构:IF 条件处理1NDIF,CASE结构:CASE 条件 OFCASE(1) 处理1CASE(2)处理2CASE(n) 处理n 3。循环结构 FOR循环结构:FOR i=1 TO n循环体END FOR WHILE循环结构:WHILE 条件循环体ENDWHILE UNTIL循环结构:REPEAT循环体 UNTIL条件,4. 模块定义和
29、调用 模块定义 PROCEDURE 模块名(参数)RETURE 模块调用 CALL模块名(参数)数据定义DECLARE 类型 变量名, 其中,类型可以有:字符、整型、实型、双精度、指针、数组及结构等类型。 5. 输入或输出GET(输入变量表)PUT(输出变量表),用户界面设计,用户界面设计问题 1. 系统响应时间 2. 用户帮助设施 3. 出错信息处理 4命令交互 用户界面设计过程 用户界面设计是一个迭代的过程,一般步骤如下: 先设计和实现用户界面原型。 用户试用该原型,向设计者提出对界面的评价。 设计者根据用户的意见修改设计并实现下一级原型。 不断进行下去,直到用户满意为止。 用户界面设计的
30、基本原则 (1)可靠性 (2)简单性 (3)易学习性和易使用性 (4)立即反馈性 用户界面设计指南 1一般交互 2. 信息显示 3. 数据输入,数据输入输出设计,输入设计 输出设计,数据安全设计,软件系统发生的事故类型。 数据安全控制方法: 1检查数据的正确性、完整性 2检查用户使用权限 3系统运行日志 4监督检查违规行为 5加密 6数据安全受破坏时的措施,详细设计文档与复审,详细设计说明书 操作手册编写提示 详细设计的复审用下列形式之一完成: 设计者和设计组的另一成员一起进行静态检查; 由检查小组进行较正式的软件结构设计检查; 由检查小组进行正式的设计检查,对软件设计质量给出评价。,小结,过
31、程设计应在数据设计、概要设计、接口设计完成之后进行, 是详细设计阶段应完成的主要任务。 详细设计阶段使用的工具:流程图、N_S图、PAD图、判定表、判定树、过程设计语言(PDL)等,读者应当熟练掌握这些工具。 用户界面设计的质量直接影响用户对软件产品的评价, 应对用户界面设计给以足够的重视。,软件实现,选择程序设计语言 程序设计风格 软件测试基础 单元测试 集成测试 确认测试 白盒测试 黑盒测试,选择程序设计语言,程序设计语言的分类 选用高级程序设计语言的实用标准,程序设计语言的分类,根据程序设计语言的发展历程基本上可以分为低级语言和高级语言两大类。 (1) 低级语言低级语言包括机器语言和汇编
32、语言。这两种语言都依赖于相应的计算机硬件。机器语言属于第一代语言,汇编语言属于第二代语言 。,(2) 高级语言 高级语言包括第三代程序设计语言和第四代超高级程序设计语言(简称4GL)。第三代程序设计语言利用类英语的语句和命令,尽量不再指导计算机如何去完成一项操作,如BASIC、COBOL和FORTRAN等。第四代程序设计语言比第三代程序设计语言更像英语但过程更弱,与自然语言非常接近,它兼有过程性和非过程性的两重特性,如数据库查询语言、程序生成器等。,高级语言分类,分别从应用特点和语言内在特点两个不同角度对高级语言进行分类,2 程序设计语言的选择,通常选择程序设计语言时优先考虑高级语言,而不是低
33、级语言(主要是汇编语言)。这是因为高级语言明显优于低级语言。高级语言的选择可以参照以下标准。 理想标准l 为了使程序容易测试和维护以减少软件的总成本,所选用的高级语言应该有理想的模块化机制,以及可读性好的控制结构和数据结构。l 为了便于调试和提高软件可靠性,应该使编译程序能够尽可能多地发现程序中的错误。l为了降低软件开发和维护的成本,选用的高级语言应该有良好的独立编译机制。,2 程序设计语言的选择,实用标准l语言自身的特性 l软件的应用领域 l软件开发的环境 l软件开发的方法 l算法和数据结构的复杂性 l软件可移植性要求 l软件开发人员的知识,2 程序设计语言的选择,目前在软件实现中使用面向对
34、象语言非常普遍。到底应该选用面向对象语言还是非面向对象语言,关键不在于语言功能强弱。选择面向对象语言的关键因素,是语言的一致的表达能力、可重用性及可维护性。开发人员在选择面向对象语言时,除了考虑上述的实用标准以外,还应该着重考虑以下一些实际因素:l可重用性。 l类库和开发环境。 l将来能否占主导地位。 l其他因素。,编码风格,编码风格又称程序设计风格或编程风格。编码风格实际上指编程的基本原则。 1. 好程序的标准 l能够工作,即能够满足用户的使用要求。l 可靠性高。l 使用方便。l 简单、容易理解。l 易于维护和修改。l 高效率。l 易移植性。l 可重用性。,2. 编程的基本原则,一个公认的、
35、良好的编程风格可以减少编码的错误,减少读程序的时间,从而提高软件的开发效率。为了做到这一点,应该遵循下述一些原则:l源程序文档化 l数据说明:在编写程序时,要注意数据说明的风格。 l语句构造 :构造的语句要简单、直接,不要为了提高效率而使语句更为复杂。 l输入和输出:输入输出的方式和格式应当尽量作到对用户友好,尽可能方便用户的使用。 l效率:选择良好的设计方法才是提高程序效率的根本途径,设计良好的数据结构与算法,都是提高程序效率的重要方法。,2. 编程的基本原则,由于面向对象的程序设计语言所具有的特殊性,面向对象编程原则,除了遵循上述编程的基本原则之外,还包括为适应面向对象方法所特有的概念(如
36、继承性)而必须遵循的一些新原则:l提高可重用性 l提高可扩充性 l提高健壮性 总之,在编码时要善于积累编程经验,培养和学习良好的编程风格,使程序清晰易懂,易于测试与维护,从而提高软件的质量。,常用程序设计工具简介,目前不同的程序设计语言相应的程序设计工具非常之多,而且相同的程序设计语言对应的程序设计工具随各公司不同而五花八门。但比较流行和常用的有:Microsoft系列有Visual Studio和Visual Studio.NET;Borland系列有Delphi、Jbuilder、C+ Builder;其它还有Eclipse、Visual Age for Java、Visual Caf f
37、or Java、PowerBuilder和Macromedia系列等。,程序设计风格,源程序文档编写规则 数据说明 语句构造要简单直接 输入输出语句 程序效率,调试,调试(debug)又称排错或纠错。调试的任务就是根据测试时所发现的错误,找出原因和具体的位置,进行改正。准确的说,调试工作包括:对错误进行定位并分析原因,即诊断;对于错误部分重新编码以改正错误;重新测试。调试工作的重点是诊断,通常诊断约占调试工作量的90以上。,调试,软件测试应该由他人进行,调试工作主要由程序开发人员来进行,谁开发的程序就由谁来进行调试。,调试,调试是一件很困难的工作,之所以困难,是由于人的心理因素以及技术方面的原
38、因而致,其中心理方面的原因可能多于技术方面的原因。,调试原则,1. 诊断原则 用头脑去分析思考与错误征兆有关的信息。 避开死胡同。 只把调试工具当做辅助手段来使用。 避免用猜测或试探的办法,最多只能把它当作最后手段。,调试原则,2. 修改原则 修改错误前一定要仔细考虑。 在出现错误的地方,很可能还有别的错误。 修改错误的一个常见失误是只修改了这个错误的征兆或这个错误的表现,而没有修改错误的本质。 当心修正一个错误的同时有可能会引入新的错误。 修改错误的过程将迫使人们暂时回到程序设计阶段。 修改源代码程序,不要改变目标代码。,调试步骤,调试的步骤如下: 调试过程从执行一个测试用例开始,然后从错误
39、的外部表现形式入手,确定程序中出错位置; 研究有关部分的程序,找出错误的内在原因; 修改设计和代码,以排除这个错误;,调试步骤,重复进行暴露了这个错误的原始测试或某些有关测试,以确认: 1) 是否排除了该错误;2) 是否引进了新的错误。 如果所做的修正无效,则撤消这次改动,恢复程序修改之前的状态。重复上述过程,直到找到一个有效的解决办法为止。,调试方法,1.试探法:试探法又称蛮干法。该方法一般由调试人员分析错误的症状,猜测问题的所在位置,利用在程序中设置输出语句,分析寄存器、存储器的内容等手段来获得错误的线索,一步步地试探和分析出错误所在。该方法的排错能力主要依赖于调试人员的经验、直觉和运气。
40、,调试方法,2 回溯法:调试人员从发现错误症状的位置开始,人工沿着程序的控制流程往回跟踪程序代码,直到找出错误根源为止。这是一种适合于小型程序排错的有效方法,对于大规模程序,由于其需要回溯的路径太多而变得不可操作。,调试方法,3.对分查找法:对分查找法的基本思路是,如果已经知道每个变量在程序内若干个关键点的正确值,则可以用赋值语句或输入语句在程序中点附近“注入”这些变量的正确值,然后运行程序并检查所得到的输出。如果输出结果是正确的,则错误原因在程序的前半部分;反之,错误原因在程序的后半部分。对错误原因所在的那部分再重复使用这个方法,直到把出错范围缩小到容易诊断的程度为止。,调试方法,4. 归纳
41、法:归纳法是一种从特殊推断一般的系统化思考方法。归纳法排错的基本思想是:从一些错误征兆的线索着手,通过分析它们之间的关系来找出错误。它一般从测试所暴露的问题出发,收集所有正确或不正确的数据,分析它们之间的关系,提出假想的错误原因,用这些数据来证明或反驳,从而查出错误所在。,5.演绎法:演绎法是一种从一般原理或前提出发,经过排除和精化的过程来推导出结论的思考方法。演绎法排错是测试人员根据测试结果,列出所有可能的错误原因。分析已有的数据,排除不可能和彼此矛盾的原因。对余下的原因,选择可能性最大的,利用已有的数据完善该假设,使假设更具体。用假设来解释所有的原始测试结果,如果能解释这一切,则假设得以证
42、实,也就找出错误;否则,要么是假设不完备或不成立,要么有多个错误同时存在,需要重新分析,提出新的假设,直到发现错误为止。,调试方法,对分查找法、归纳法和演绎法都是对错误发生有关的数据进行分析,来寻找到潜在的原因,因此它们都属于原因排除法。,小结,软件实现包括编码和测试两个阶段。 编码目的是把详细设计的结果翻译成用选定的语言书写的源程序。程序的质量主要是由设计的质量决定的。但是,编码的风格和使用的语言,对编码质量也有重要的影响。具体选用哪种程序设计语言?一般不使用汇编语言写程序,而使用高级程序设计语言。至于具体选用哪种高级程序设计语言,则不仅要考虑语言本身的特点,还应该考虑使用环境等一系列实际因
43、素。,小结,调试是要准确确定测试中的错误位置,并加以改正的过程。为了改正错误往往需要修正原来的设计,并使用正确的原则和方法,尽量避免在调试过程中引进新错误。,测试的基本理论及方法,对软件测试的误解 如何理解软件测试 软件测试的定义 软件测试的对象 软件测试分类和比较 软件测试的目的 软件测试组织 软件测试规范 软件测试的内容和技术 WEB应用测试,对软件测试的误解,如果发布出去的软件有质量问题,那是软件测试人员的错. 软件测试技术要求不高,至少比编程容易多了. 软件测试随便找一个能力差的人就能做. 有时间就多测试一些,来不及就少测试一些. 软件测试是测试人员的事,与开发人员无关. 设计-实现-
44、测试,软件测试是开发后期的一个阶段,如何理解软件测试,软件测试是一种有效的提高软件质量的手段,但即使在投入上有所保证,测试也不能百分为百发现所有质量隐患.况且软件质量并不仅仅是测试出来的. 很多人认为软件测试就是运行一下软件,看看结果对不对.但实际上,如何在有限的投入下,提高软件测试的效率和产出是一件很见功底的事.好的测试人员不仅要掌握各种测试技术,还要具备丰富的编程经验和对BUG的敏感.测试的复杂之处,除了测试技术问题之外,还有测试管理问题. 测试不是可有可无,随心所欲的.规范化的软件开发需要对软件测试早做计划,分配必要的时间,人力和财力等资源,并将其作为项目管理的一个部分加以控制和协调.
45、开发和测试是软件项目相辅相成的两个过程,人员间的交流,协作和配合是提高整体效率的重要因素.,软件产品开发完毕,再进行测试的观念是有悖于生命周期理论的.软件产品质量问题越晚发现,修复的代价越大.,需求,设计,编程,内部测试,外部测试,发布,修正BUG的代价,一些常识和经验之谈 测试能提高软件的质量,但是提高质量不能依赖测试。 测试只能证明缺陷存在,不能证明缺陷不存在。“彻底地测试”难以成为现实,要考虑时间、费用等限制,不允许无休止地测试。我们应当祈祷:软件的缺陷在产品被淘汰之前一直没有机会发作。 测试的主要困难是不知道如何进行有效地测试,也不知道什么时候可以放心地结束测试。 每个开发人员应当测试
46、自己的程序(份内之事),但是不能作为该程序已经通过测试的依据(所以项目需要独立测试人员)。 80-20原则:80的缺陷聚集在20的模块中,经常出错的模块改错后还会经常出错 测试应当循序渐进,不要企图一次性干完,注意“欲速则不达”。,软件测试的定义,软件测试是为了发现错误而执行程序的过程 使用人工和自动手段来运行或测试某个系统的过程,其目的在于检验它是否满足规定的需求或弄清楚预期结果与实际结果之间的差别。,软件测试不等于程序测试.软件测试贯穿于软件定义和开发的整个期间.需求分析,概要设计,详细设计,以及程序编码等各个阶段所得到的文档,包括需求规格说明,概要设计规格说明,详细设计规格说明以及源程序
47、,都是软件测试的对象.,软件测试的对象,软件生存各个阶段间的确认和验证,软件配置:包括软件需求规格说明、软件设计规格说明、源代码 等;测试配置:包括测试计划、测试用例、测试驱动程序等。实际上,在整个软件工程过程中,测试配置只是软件配置的一个子集。测试工具:为提高软件测试效率,可使用测试工具支持测试工具。例如:测试数据自动生成程序、测试结果分析程序等。,测试的目的,测试是程序的执行过程,目的在于发现错误; 一个好的测试用例在于发现至今未发现的错误; 一个成功的测试是发现了至今的错误的测试.,测试的种类,测试的分类与比较,测试方式 白盒测试:关心软件内部设计和程序实现,主要测试依据是设计文档 黑盒
48、测试:不关心软件内部,只关心输入输出,主要测试依据是需求文档测试阶段 单元测试、集成测试、系统测试、验收测试。是“从小到大”、“由内至外”、“循序渐进”的测试过程,体现了“分而治之”的思想。 单元测试的粒度最小,一般由开发小组采用白盒方式来测试,主要测试单元是否符合“设计”。 集成测试界于单元测试和系统测试之间,起到“桥梁作用”,一般由开发小组采用白盒加黑盒的方式来测试,既要验证“设计”又要验证“需求”。 系统测试的粒度最大,一般由独立测试小组采用黑盒方式来测试,主要测试系统是否符合“需求规格说明书”。 验收测试与系统测试非常相似,主要区别是测试人员不同,验收测试由用户执行。,开发与测试的 W
49、 型关系 如果软件开发过程采用严格的瀑布模型,那么开发与测试有“W”型的对应关系 。,测试内容 接口与路径测试。 功能测试、健壮性测试、性能测试、用户界面测试、安全性测试、压力测试、可靠性测试、安装/反安装测试,黑盒测试与白盒测试的比较,问题1:有了“黑盒”测试为什么还要“白盒”测试? 黑盒测试只能观察软件的外部表现,即使软件的输入输出都是正确的,却并不能说明软件就是正确的。因为程序有可能用错误的运算方式得出正确的结果,例如“负负得正,错错得对”,只有白盒测试才能发现真正的原因。 白盒测试能发现程序里的隐患,象内存泄漏、误差累计问题。在这方面,黑盒测试存在严重的不足。 问题2:由于单元测试要写
50、测试驱动程序,非常麻烦,能否等到整个系统全部开发完后,再集中精力进行一次性地单元测试呢? 如果这样做,在开发过程中,缺陷会越积越多并且分布得更广、隐藏得更深,反而导致测试与改错的代价大大增加。最糟糕的是无法估计测试与改错的工作量,使进度失去控制。因此为图眼前省事而省略单元测试或者“偷工减料”,是“得不偿失”的做法。 问题3:如果每个单元都通过了测试,把它们集成一起难道会有什么不妥吗?集成测试是否多此一举? 要把N个单元集成一起肯定靠接口耦合,这时可能会产生在单元测试中无法发现的问题。例如:数据通过不同的接口时可能出错;几个函数关联在一起时可能达不到预期的功能;在某个单元里可以接受的误差可能在集成后被扩大到无法接受的程度。所以集成测试是必要的,不是多此一举。,