第一章:软件开发概述
第二章:模块化软件构造
第三章:面向对象的软件构造
第四章:数据处理的软件构造
第五章:用户交互的软件构造
学习以键盘为输入设备、屏幕为输出设备的用户交互界面的;
软件构造,包括如何把多个模块实现的功能整合到一个程序的软件集成。
通过交互式语音应答系统的层次结构的菜单交互界面的构造,学习用户功能与实现代码的关联。
初步学习用户交互的基本概念、基本原理、设计原则及常用的静态测试方法。
学习软件集成及其相关的集成测试、回归测试、基于模型的测试技术。
5.1程序及其功能的使用
5.1.1程序的两个观察视角
程序可以从两个角度观察和理解
- 程序员是程序的产生者。他们看到程序的内部组成——变量、语句、函数、类及其关联所形成的结构。程序员通过编写函数、方法、类等程序单元,实现用户要求的功能。
- 对用户而言,程序实现其需求,用户可以使用程序完成所要求的功能。
用户使用程序——用户交互
- 不论是传统的命令行、菜单选择的程序输入/输出,还是流行的图形用户界面GUI、触摸式,以及声控、手势或脑控制的操作方式,都是用户使用程序、与程序进行交互的形式。
- 程序最终是要把用户的要求或指令转换成相应的函数或方法。
5.1.2多个功能程序的整合
当一个程序不止一个功能(用户角度),或者包含多个函数(程序员角度)时,如何呈现并执行这些功能涉及两方面问题:
- (1)如何把若干功能合理地呈现出来,便于用户操作;(用户界面或交互的设计)
- (2)如何把若干函数整合,便于程序执行。(程序的集成)
用户界面可以视为集成程序的一种方式。
5.1.3多个功能的组织与呈现
- 程序的用户界面集成实质上就是如何把一组功能合理地组织并呈现给用户使用。
- 如果不考虑文字或图形的方式,可以把功能以某种顺序全部罗列出来,或者把所有功能按照某个规则分组、分层地结构化地呈现。例如︰文件目录。
- 用户界面:把程序众多功能划分成组(抽象),按照层次结构,从抽象到具体直至一个功能,为用户使用提供了方便易用的界面。这种用户交互程序的形式无论是采用文字还是图形,基本原理都一样。
- 目前的移动应用APP众多,手机屏幕大小有限,有两种基本方式组织应用:
- 一种方式是以屏为单位连续摆放应用图标,排满后增加一个屏幕,继续顺序放置;
- 另一种方式是文件夹,它可以按照顺序放置把一定数量的应用。
- 图形化界面可以通过单击表示功能或应用的图标进入下一级菜单,直接打开应用或某个功能。
- 菜单的设计可以是自]顶向下的方式,即从抽象的主菜单(根)逐步具体到子菜单,直至原子功能;
- 也可以是自底向上的方式,把具体的功能逐步抽象、分组成子菜单,直至主菜单。
- 无论哪种策略,都需要运用抽象和分类的基本原则。
5.1.4基于菜单式功能选择的用户交互
模拟实现
- 以便让用户体验界面是否合适。
- 所谓模拟,指的是没有实现或不调用已经实现的用户功能,而是用简单的、通常只包含一条打印语句的模拟函数代替。模拟程序的主要目的是检测菜单结构、菜单项的访问及菜单之间的跳转。
- 如果已经实现了某个用户功能,则可以调用执行。
- 最终,程序要经过集成的策略和步骤,用实现的用户功能替换每个模拟函数。
5.2用户交互概述
5.2.1基本概念
含义:
- 用户交互或人机交互是有关交互式计算机系统的设计、评估、实现及与之相关现象的学科。
- 可以把人机交互理解为是关于可用性的学习和实践,是关于理解和构建用户乐于使用且易于使用的软件和技术,并能在使用时发现产品有效性的学科。
- 人机交互的目的是开发及提高计算机相关系统的安全性效用、有效性、高效性和可用性。
5.2.2交互设备
含义:借助交互设备对计算机系统输入数据、指令或信息,并从系统获得反馈。
一个计算机系统通常使用以下几种交互设备:
- 键盘是文本输入的主要设备,也是应用最广的输入设备。
- 定位设备在屏幕上通过指点物体实现对物体的操作或完成某个功能。如:鼠标、光笔、触摸屏/板、轨迹球、操纵杆等。
- 显示器是用户从计算机得到反馈的主要输出设备。
5.2.3交互风格
设计者完成任务分析并识别出任务对象和动作时,可以选择以下5种交互风格:
- 直接操纵:主要针对可视化的用户交互,用户通过单击可视化对象和动作快速执行任务,并观察到结果(如把某个图标拖放到垃圾桶中)。
- 菜单选择:用户阅读选项列表,然后选择最合适自己任务的选项,系统分析和处理输入、转换成相应的功能。
- 表格填充:用户看到适当的提示,在需要的地方输入数字,系统分析和处理输入、转换成内部程序的参数。
- 命令语言:对常用用户而言,命令语言提供强烈的掌控感。如Linux操作系统的命令。
- 自然语言∶用自然语言(如汉语)发出命令和接收相应的方式操作计算机(软件)
5.2.4交互界面
交互界面:
- 是人和计算机进行信息交换的通道,人通过交互界面向计算机输入信息、进行操作,计算机则通过交互界面向用户提供信息,以供阅读、分析和判断。
- 用户界面是实现用户交互、使用程序的手段。用户交互是使用程序的本质。
- 只能通过特定的界面才能让用户更好地体验程序。
以下是几种常见的基本人机交互界面。
- 命令语言用户界面,比如DOS操作系统(用cmd进入)或Linux
- 图形用户界面GUI。
- 直接操作用户界面。
- 多媒体用户界面,引入了动画、音频、视频等交互媒体手段
- 多通道用户界面。是为了消除当前GUI和多媒体用户界面通信宽带不平衡的瓶颈,综合采用视线、语音、手势等新的交互通道、设备和交互技术,使用户利用多个通道以自然、并行、协作的方式进行人机对话,通过整合来自多个通道的精确和不精确的输入来捕捉用户的交互意图,提高人机交互的自然性和高效性。
- 虚拟现实技术。比以前任何人机交互形式都有希望彻底实现以人为中心的人机交互界面。
5.2.5交互设计的原则*
人机交互涉及心理学、认知科学、计算机科学、产品设计、图形设计等。
3条基本原则:
- 学习性:指的是新的用户能用它进行有效的交互并获得最大的性能。
- 灵活性:是指用户和系统能以多种方式交换信息。
- 健壮性:是指在决定成就和目标评估方面对用户提供的支持程度。
8条黄金规则:
- (1)尽量保持一致。
- (2)满足普遍可用性。
- (3)提供信息反馈。
- (4)设计对话框以产生结束信息。
- (5)预防并成立错误。
- (6 )允许撤销操作。
- (7)支持内部控制点。
- (8)减轻短时记忆负担。
5.3用户交互的开发
5.3.1交互设计基本过程
- 标识和建立用户需求。交互设计的用户需求包括:功能需求、数据需求、使用环境和可用性需求。
- 提出满足需求的候选设计方案。概念设计和物理设计
- 构建交互式版本。开发用户交互模型,通常是可运行的原型软件,包含用户交互界面、交互形式、完成任务的基本流程等。
- 设计评估。即评估交互设计的可运行和可接受性。
5.3.2快速原型法
快速原型:
- 是快速建立起来的可以在计算机上运行的程序,它所能完成的功能往往是最终产品能完成的功能的一个子集。
使用快速原型目的:
- 在获得用户交互基本需求说明的基础上,快速建立一个可以运行的软件,使用户及时运行和看到交互的形式和使用效果,并对交互需求说明进行补充和精化,提出改进意见;
- 开发人员进一步修改完善,如此循环迭代,直到得到一个用户满意的模型为止。
( 1)功能选择
原型和最终的软件系统不同,两者在功能范围上的区别主要有以下两个方面:
- 最终系统是软件需求全部功能的实现,而原型只实现所选择的部分功能;
- 最终系统对每个软件需求都要求详细实现,而原型仅仅是为了试验和演示用的,部分功能需求可以忽略或者模拟实现。
(2)构造原型
- 根据用户初步需求,开发出一个可以运行的、主要包含界面的系统,它应满足用户提出的基本要求。
(3)运行和评价原型
- 用户在试用中能亲自参加和面对一个可以实际运行和操作的模型,能较为直观和明确地进一步提出需求,提出修改意见。
(4)修改和完善原型
- 根据修改意见进行修改,修改系统原型,然后再进行试用和评价。
- 这样经过有限次的循环反复,逐步提高和完善,直到得到一个用户满意的系统模型为止。
5.4静态测试
5.4.1程序的可用性与静态测试
程序的可用性指的是程序是否有用,包括用户界面是否易用,主要有三个特征:
- 有效性,是用户完成特定任务和达成特定目标时所具有的正确和完整程度。
- 效率,是用户正确完成任务的程度与所用资源(如时间)的比率。
- 主观满意度,是用户在使用产品过程中所感受到的主观满意和接受程度。
可用性的指标:
- 易学性——产品是否易于学习;
- 交互效率——客户使用产品完成具体任务的效率;
- 易记性——客户搁置某产品一段时间后是否仍然记得如何操作;
- 容错性——操作错误出现的频率和严重程度如何。
根据是否运行待测程序,软件测试分为动态测试和静态测试。
- 动态测试通过设计有效的测试用例,运行观察程序的运行行为、状态变化及输出等来判断软件是否存在问题。
- 静态测试不执行程序,而是通过阅读和分析代码及相关材料、发现软件错误的活动。静态测试又称人工手动测试,是动态测试和自动化测试的补充,是软件质量保障的重要组成。
静态测试的主要作用包括:
- 发现程序在功能、逻辑构造方面的错误;
- 验证实现的程序在需求和设计方面符合用户的要求;确认程序符合预先定义的开发规范和标准;
- 保证软件开发过程的规范性;
- 有助于程序员之间相互学习。
静态测试类型:·
- 桌面检查、
- 代码走查、
- 正式审查、
- 司行评审、
- 静态程序分析。
5.4.2桌面检查
程序员个人模拟计算机“阅读”程序,发现代码错误的方法。
5.4.3代码走查与正式审查
代码走查(walkthrough )和正式审查(inspection )
- 是通过组织其他程序员共同参与的团队检查,是对传统的程序员桌面检查方式的改进。
- 代码走查至少由两人组成,其中一人协调走查,另一人扮演测试者。
- 在走查过程中,由测试者提出一批测试用例,在走查会议上对每个测试用头脑来执行程序,在纸上或黑板上演变程序的执行状态,从而发现程序错误。
- 在这个过程中,测试用例用作怀疑程序逻辑、计算或控制错误的参照,测试用例本身并不重要。
代码走查检查程序的错误:
数据引用错误、数据声明错误、逻辑错误、计算错误、判断错误、控制流程错误、接口错误、输入/输出错误。
代码开发人员对照讲解设计意图和程序代码,特别是对有异议之处进行解释,有助于验证设计和实现之间的一致性。
5.4.4正式审查
含义
- —种正式的结构化检查和评估方法,一般有计划、流程、结果和追查。
- 审查小组至少有4人:一人负责协调、分发材料、安排进程、确保错误随时得到改正,被检测试程序的编码人员,其他程序开发人员和一名测试人员。
- 审查小组最好还要包括丰富经验的程序员、编程语言的专家、未来的代码维护人员、其他项目组成员,以及同组的程序员。
代码审查通过会议实施,基本过程如下∶
- 协调人在代码检查前几天分发程序清单、编码规范和检查清单;编码人员讲述程序的逻辑结构,其他人员提问题并判断是否存在错误;
- 对照编码规范、检查清单分析程序;
- 审查人员的注意力集中在发现错误而非纠正错误上(非调试);会议结束后,程序员会得到一份已发现错误的清单。如果发现重大缺陷,在修改之后,还要重新召开会议审议。
采用正式审查时要注意以下几点:
- 以会议形式审查,要制定会议目标、流程和规则,结束后要编写报告;
- 按缺陷检查表逐项检查,避免漫无目标检查;发现问题适当记录,避免现场讨论和修改;发现重大缺陷,改正后会议需要重开;
- 检查要点是缺陷检查表,根据不同的项目,该表要不断积累和完善。
5.4.5同行评审
同行评审(reviewing )
- 是对代码的全面质量评审,包括代码的可维护性、可扩展性、可使用性,以及安全和编程规范是否得到遵守是软件开发队伍对程序质量和信赖性进行的自我评估。
- 评审时,一般挑选一个程序员作为组织者,由他再选择若干同行参加评审。
- 同行必须是真实的,即具有被评审者相同的背景(例如,均是Java程序员)。
- 每个评审者都要挑选两段程序进行评审,比较和给出这两段程序质量上的优缺点。
- 可以定义更详细的评价标准,例如,对发现问题的严重程度分等级或加权,从而定量地说明代码的质量和可信赖程序。
5.4.6检查表
正式审查和同行评审都需要缺陷检查表或检查单
- 它列出了容易出现的典型错误,以便让编程人员和评审人员集中精力,依据代码检查单的问题,实施静态测试,并记录代码中的错误,以便在后期总结和统计错误的类型、原因等,从而避免和预防代码错误。
- 例如,Myers 从数据引用错误、数据声明错误、计算错误、判断错误、控制流程错误、接口错误、输入/输出错误等方面给出检查单。
5.4.7静态程序分析
- 通过扫描源程序而发现可能的故障或异常。它不要求程序运行,因而属于静态测试。
- 它分析程序正文,识别程序中语句的差异,检测语句构造是否规范、推测程序的控制流、在很多场合计算出程序所有可能的值。
- 静态程序分析补充了语言编译器提供的错误检测功能。
- 静态分析的目的是引起程序员对程序中异常(如未初始化的变量、未使用的变量、数值超出范围)的警觉。尽管这些异常不一定是错误条件,但是,它们经常是程序设计错误、遗漏或疏忽的结果所造成的。
- 静态程序分析器不仅检测代码的故障,也检查代码是否遵循了规定的规范或风格。图为Java静态分析工具Checkstyle截图。
5.5软件集成与测试
软件集成:
- 把实现各个功能的模块、数据、用户交互界面等模块组织起来,构建成一个完整的应用程序的过程称为软件集成。
- 与之相对应的是集成测试。
- 软件集成主要体现并依赖于软件设计或软件架构设计,明确组成软件的各个模块的功能和接口。
- 只要严格按照要求开发,模块之间就能通过良好定义的接口整合在一起,构成一个完整的软件系统。
功能集成和界面集成是基本的软件集成:
- 功能集成指把具有不同功能的程序或模块(函数、类、接口、库等))通过函数调用、消息传递、继承、包含、引用及共同的数据集等方式关联起来,作为一个整体完成更复杂的功能或提供比新程序组成单元更多的功能。
- 界面集成指为具有不同功能的程序或模块提供一个统一的用户交互界面,方便用户使用。
软件集成含三个方面:
- 集成策略指对软件的组成单元按照什么顺序组织起来、构成一个软件,考虑的问题包括软件组成单元之间的依赖关系、开发任务分配等。
- 集成内容主要包括流程、数据、功能和界面。
- 集成技术指的是如何通过语法、语义、逻辑等关系把软件的组成单元“粘合”起来。
集成测试的主要目的:
- 是检测软件组成单元的接口是否符合要求,
- 它们的交互是否流畅,
- 集成后的软件能否按照设计合作完成要求的功能等。
- 集成的前提是各个组成单元已经完成开发并通过了(单元)测试。
5.5.1 驱动模块和桩模块
在集成软件及其组成单元时,为了使得集成的软件可以编译和运行,需要模拟集成时尚未完成的组成单元、相关联的环境之间的交互。
常见的基本的模拟程序有驱动模块和桩模块。
- 驱动模块的主要任务是搜集或产生数据、把数据传给待测程序、启动和执行它。
使用模拟程序的主要原因和目的如下:
- (1)模拟复杂的代码。增量集成代码时,要关注模块间的接口是否一致、模块的交互逻辑是否矛盾、模块的合作是否流畅等。采用模拟程序可以分离关注点。
- (2)模拟尚未实现的代码。
- (3)模拟程序的整体性。把所有或部分代码整合到一起,测试运行一次可能会耗费资源、时间等,为了检测程序的整体结构、用户界面、全局逻辑、关键功能等,采用模拟程序替换实际程序可以加快实现特定的目标。
5.5.2集成策略
传统方法用树状的结构图示意一个程序的组织结构。图5.11表示了案例程序的功能结构,其中方框图表示程序的功能模块,连线表示模块之间的控制关系或者功能的组成;树的根表示总控模块,它调用其他模块完成程序的所有功能。基于程序结构的功能分解属于基本的集成策略,主要有如下5种方式︰一次性集成、增式集成、自底向上集成、自顶向下集成、基干集成。
1.一次性集成
- 构成一个程序的所有模块在一次集成过程中组装成最终的软件。对图5.11而言,一次性集成就是,首先完成这16个模块的开发和测试,然后放在一起构成最终的软件。
- 难以发现和修改在一次性集成中出现的错误。
2.增式集成
- 增式集成,即以一个基本模块或主模块为基础,每次增加一个或一组模块形成部分程序,在确保正确后再逐步增加模块,直至所有模块都集成至部分程序构成软件整体。
- 增量集成中出现的错误容易定位和修复。
3﹒自顶向下集成
- 集成模块从根部的控制模块开始,以控制层次的顺序,逐次增加模块,直至形成整个程序的增式集成方式,称为自顶向下集成。
- 增量集成时要为其他尚未集成的模块编写桩,通过测试后,再逐步用模块替换桩、执行集成与测试。
自顶向下集成测试的步骤:
- (1)测试主模块,以桩模块代替没有完成开发的下级模块
- (2)依次用实现的模块代替桩模块;
- (3)每集成一个模块,就测试部分程序,重点是新增的模块及其与部分程序的交互;
- (4)必要时进行回归测试——重复之前的测试。
- 自顶向下集成策略的优点:在集成的任何时候都有一个可以运行的程序。
- 缺点:桩模块的开发代价有时会较大,而且正是由于桩模块的存在使得部分程序难以得到充分的测试
4.自底向上集成
- 选择独立性最大或者对其他模块依赖性最小的模块开始,从程序结构图的底部开始,逐次增加控制模块,直至完成整个程序。
- 需要编写驱动模块。
自底向上集成测试的步骤∶
- (1)编写调用底层模块的驱动模块;
- (2)测试驱动模块与底层模块组成的部分程序;
- (3)用实现的控制模块替换驱动模块,并测试部分程序的功能;
- (4)必要时进行回归测试——重复之前的测试。
自底向上集成的优点:
(1)底层模块的测试与集成可以独立、平行地进行;
(2)不需要桩模块。
缺点:
(1)驱动模块的开发一般比较耗费;
(2)难以充分测试高层模块的可操作性。
5 .基干集成
选择一个程序的基干模块,将自顶向下与自底向上的集成方式结合起来,逐步地集成其他模块的策略,称为基干集成,又称三明治或混合策略。
优点:
(1)减轻了自顶向下与自底向上的不利因素;(2)集成过程总有一个可运行的部分程序;(3)适合大型、复杂软件的集成。
缺点:
(1)需要仔细分析系统结构和模块间依赖性,同时要分析用户需求的优先性;
(2)有时需要开发桩模块和驱动模块,工作量较大;(3)局部采用了一次性集成,接口测试可能不充分。
5.5.3回归测试
- 复用之前的测试对集成后的软件或其中的某个子集重新进行测试,以确保修改的模块或其他程序变更没有传播不期望的副作用。这种测试称为回归测试。
- 它是保证在程序修改的情况下保证程序功能正常的一致性测试策略和方法。
- 回归测试无须对程序进行全面测试,而是根据修改情况进行有限的测试。可以选用测试库中的测试用例,也可以增加新的测试用例。
回归测试的基本过程是∶
- (1)识别软件中发生变更、受影响的部分;
- (2)选择可以复用的测试用例,用以验证程序的变更不改变程序的原有功能;
- (3)补充新的测试用例,侧重检测可能会受到影响的功能或软件子集,特别是包含新增或修改的部分,以及与其他软件部分的联系;
- (4)依据一定的策略对程序进行测试。
实施回归测试策略时,
应该兼顾效率和有效性两个方面,可以采用不同的测试用例选择方式:
- ( 1)再测试全部测试用例。
- (2)基于风险选择测试。
- (3)再测试修改的部分。
5.5.4集成测试与策略
集成测试关注模块间的调用、消息传递、数据传输与处理是否正确及不同模块的可组合性,它们之间的协作能否完成一个包含了若干操作的特定的应用功能,即是否能实现用户的功能要求。
集成测试应该遵循下列几条基本原则∶
- ( 1)应该测试所有的公共接口;
- (2)要充分测试关键模块;
- ( 3)应该按照一定的层次实施集成测试;
- (4)选择与开发、软件集成相匹配的测试策略;
- (5)集成后任何模块接口和实现的变动都要进行回归测试
协作集成与测试的过程如下:
- (1)对待集成的模块依赖性、性关系等逻辑关系进行分析,确定出用户指定或密切关联的子系统;
- (2)运用之前的策略集成并测试每个子系统;
5.6.1软件建模
- 模型可以是模拟,也可以是样板。
- 对尚不存在、拟构建的客体建立的模型,称为样板。它可以作为样板用以创建设想中的客体。
- 模拟是对已经存在客体的简化而建立的,模型是对客体的,它的主要作用是理解和分析客体,进而作为改进的手段,建立样本模型,创造新的客体。
5.6.2持续集成
- 持续集成是敏捷开发方法的一项基本的软件开发实践。
- 项目成员频繁地集成他们的工作,使得每天都有多次集成的代码。
- 每个集成都由自动构建验证,尽快地发现错误。持续集成的核心包括自动化构建、自动化测试及版本控制中心等工具。
- 构建是执行编码、测试、检查和交付软件的一组活动。
- 集成构建就是把软件模块(程序、数据和文件)结合到一起形成软件系统的活动。
- 所谓自动,就是通过编写可以运行的脚本程序,完成诸如代码测试、构建等,无须人工干预。