基于软件危机产生的主、客观原因,应从软件工程技术和软件工程管理两方面来采取措施,防范软件危机的发生。
产生软件危机的原因可以归纳为主、客观两个方面。
采用**工程化的概念、原理、技术和方法**进行软件的开发与维护,是指导软件开发和维护的工程性学科
瀑布模型(waterfall model)是软件工程最早的范例,也称经典生命周期,它提出了一个系统的、顺序的软件开发方法,从用户需求规格说明开始,通过计划、建模、构建和部署的过程,最终提供一个完整的软件并提供持续的技术支持。
该模型先对系统最核心或最清晰的需求进行分析、设计、实现、测试,再按优先级逐步对后续需求进行上述工作,并集成到系统中,逐步形成一个完整系统。
快速原型是快速建立起来的可以在计算机上运行的程序
螺旋模型结合了原型的迭代性质和瀑布模型的系统性和可控性特点,能快速开发软件的增量版本。
大型系统和软件。
喷泉模型主要用于面向对象的软件项目,软件的某个部分通常被重复多次,相关对象在每次迭代中随之加入渐进的软件成分。各活动之间 无明显边界,例如设计和实现之间没有明显的 边界,这也称为“喷泉模型的无间隙性”。由于对象概念的引入,表达分析、设计及实现等 活动只用对象类和关系,从而可以较容易地实现活动的迭代和无间隙
喷泉模型不像瀑布模型那样,需要分析活动结束后才开始设计活动,设计活动结束后才开始编码活动。 该模型的各个阶段没有明显的界限,开发人员可以同步进行开发。其优点是**可以提高软件项目开发效率, 节省开发时间,适应于面向对象的软件开发过程**。
由于喷泉模型在各个开发阶段是重叠的,因此在开发过程中需要大量的开发人员,因此不利于项目的管理。此外这种模型**要求严格管理文档,使得审核的 难度加大**,尤其是面对可能随时加入各种信息、需求 与资料的情况。
软件的利益相关方对目标软件系统的**功能、质量**等方面的期望,以及对目标软件系统在运行环境、资源消耗、提交进度等方面的要求与约束。
功能建模的思想就是用抽象模型的概念,按照软件内部数据传递、变换的关系,自顶向下逐层分解,直到找到满足功能要求的所有可实现的软件为止。
数据流图用于标识系统中的数据流动、处理和存储的过程。展示了数据流经系统的全貌,特别适合用于事务处理系统和其他偏重功能的系统。但是由于它是以系统的视角看问题,所以一般不会单独使用,而是会配合流程图一同使用。
基本图例:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lsqOSITc-1623381971543)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609214248702.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wcoiXTxY-1623381971544)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609214258656.png)]
一些约束:
注意数据流图的分层(书本50页)
体系结构模型
典型的数据流类型有变换型数据流和事务型数据流,数据流的类型不同,得到的系统结构也不同。
通常,一个系统中的所有数据流都可以认为是变换流,但是,当遇到有明显事务特性的数据流时,建议采用事务型映射方法进行设计。
变换型数据处理问题的工作过程大致分为3步,即取得数据、变换数据和给出数据,如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aci2Pxp3-1623381971546)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609220707899.png)]
变换型系统结构图
变换型系统的结构图由输入、中心变换和输出3部分组成。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vIW0vVUi-1623381971548)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609220731481.png)]
通常接受一项事务,根据事务处理的特点和性质,选择分派一个适当的处理单元,然后给出结果。
完成选择分派任务的部分称为事务处理中心,或分派部件。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NXA0N50Q-1623381971549)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609220811654.png)]
事务型系统结构图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WmnKckbP-1623381971550)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609220827647.png)]
在结构化分析方法中,使用实体-关系建模技术来建立数据模型。这种技术是在较高的抽象层次(概念层)上对数据库结构进行建模的流行技术。实体—关系模型表示为可视化的实体—关系图(entity-relationship diagram,ERD),也称为ER图。 ER图中仅包含3种相互关联的元素:数据对象(实体)、描述数据对象的属性及数据对象彼此间相互连接的关系。
数据对象
数据对象是目标系统所需要的复合信息的表示,所谓复合信息是具有若干不同属性的信息。在ER图中用矩形表示数据对象。
在实际问题中,数据对象(实体)可以是外部实体、事物、角色、行为或事件、组织单位、地点或结构等。
属性
属性定义数据对象的特征,如数据对象学生的学号、姓名、性别、专业等,课程的课程编号、课程名称、学分等。
在ER图中用椭圆或圆角矩形表示属性,并用无向边将属性与相关的数据对象连接在一起。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xZzTSraC-1623381971551)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609214452849.png)]
关系
不同数据对象的实例之间是有关联关系的,在ER图上用无向边表示。
在无向边的两端应标识出关联实例的数量,也称为关联的重数。
从关联重数的角度可以将关联分为3种。
(1) 一对一(1:1)关联
(2) 一对多(1:m)关联
(3) 多对多(m:n)关联
实例关联还有“必须”和“可选”之分。
关联数量的表示
在ER图中用圆圈表示所关联的实例是可选的,隐含表示“0”,没有出现圆圈就意味着是必须的。出现在连线上的短竖线可以看成是“1”。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0UwKEhhg-1623381971551)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609214559520.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AXg7JvwC-1623381971552)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609214638184.png)]
状态转换图(简称状态图)通过描绘系统的状态及引起系统状态转换的事件,来表示系统的行为。状态图中使用的主要符号如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-95sf43rg-1623381971552)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609214719735.png)]
状态是任何可以被观察到的系统行为模式,一个状态代表系统的一种行为模式,状态规定了系统对事件的响应方式。
状态可能有:初态(初始状态)、终态(最终状态)和中间态。
在一张状态图中只能有一个初态,而终态则可以有多个,也可以没有。
状态的表示:初态用实心圆表示,终态用牛眼图形表示,中间态用圆角矩形表示。
状态转换:状态图中两个状态之间带箭头的连线称为状态转换。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v8WZucZd-1623381971553)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609214914533.png)]
取款过程状态图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JzOSmH9A-1623381971554)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609215000004.png)]
面向对象的建模语言很多,目前使用最广泛的是统一建模语言(UML,Unified Modeling Language);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-88OJ0els-1623381971554)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609215508002.png)]
类图描述类和类与类之间的静态关系,它是从静态角度表示系统的,因此类图属于一种静态模型。类图是构建其他图的基础,没有类图就没有状态图、协作图等其他图,也就无法表示系统其他方面的特性。
类图显示了类(及其接口)、类的内部结构以及与其他类的联系。联系是指类元之间的联系,在类的建模中可以使用关联、聚合和泛化(继承)关系。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eNpnbf2N-1623381971555)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609215845282.png)]
用例模型
用例模型描述的是外部执行者(actor)所理解的系统功能。用例模型用于需求分析阶段,它的建立是系统开发者和用户反复讨论的结果,描述了开发者和用户对需求规格达成的共识。
在UML中,一个用例模型由若干个用例图来描述,用例图的主要元素是用例和执行者。
用例图是包括执行者、由系统边界(一个矩形)封闭的一组用例,执行者和用例之间的关联、用例间关系以及执行者的泛化的图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dF5CtYJh-1623381971556)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609215749380.png)]
“一个程序或计算机系统的软件体系结构是指系统的一个或者多个结构。结构中包括软件的构件、构件的外部可见属性以及它们之间的相互关系。外部可见属性则是指软件构件提供的服务、性能、使用特性、错误处理、共享资源使用等。”
软件设计模式是从软件设计过程中总结出来的,是针对特定问题的解决方案。建筑师C.Alexander对模式给出的经典定义是:**每个模式都描述了一个在我们的环境中不断出现的问题及该问题解决方案的核心。**在软件系统中,可以将模式划分为以下3类。
(1)体系结构模式(architectural pattern):表达了软件系统的基本结构组织形式或者结构方案,包含了一组预定义的子系统,规定了这些子系统的责任,同时还提供了用于组织和管理这些子系统的规则和向导。典型的体系结构模式如OSI参考模型。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nihxU1zz-1623381971556)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210610091947128.png)]
(2)设计模式(design pattern):为软件系统的子系统、构件或者构件之间的关系提供一个精炼之后的解决方案,描述了在特定环境下,用于解决通用软件设计问题的构件以及这些构件相互通信时的各种结构。有代表性的设计模式是Erich Gamma及其同事提出的23种设计模式。
(3)惯用法(idiom):是与编程语言相关的低级模式,描述如何实现构件的某些功能,或者利用编程语言的特性来实现构件内部要素之间的通信功能。
风格是带有一种倾向性的模式。同一个问题可以有不同的解决问题的方案或模式,但我们根据经验,通常会强烈倾向于采用特定的模式,这就是风格。
每种风格描述一种系统范畴,该范畴包括:
(1)一组构件(如数据库、计算模块)完成系统需要的某种功能;
(2)一组连接件,它们能使构件间实现“通信”、“合作”和 “协调”;
(3)约束,定义构件如何集成为一个系统;
(4)语义模型,它能使设计者通过分析系统的构成成分的性质来理解系统的整体性质。
**体系结构风格定义了一个系统家族,即一个体系结构定义一个词汇表和一组约束。**词汇表中包含一些构件和连接件类型,而这组约束指出系统是如何将这些构件和连接件组合起来的。体系结构风格反映了领域中众多系统所共有的结构和语义特性,并指导如何将各个模块和子系统有效地组织成一个完整的系统。
对体系结构风格的研究和实践为大粒度的软件复用提供了可能。
随着应用的发展和完善,某些带有整体性的应用模式被逐渐固定下来,形成特定的框架,包括基本构成元素和关系。框架是特定应用领域问题的体系结构模式,框架定义了基本构成单元和关系后,开发者就可以集中精力解决业务逻辑问题。
在组织形式上,框架是一个待实例化的完整系统,定义了软件系统的元素和关系,创建了基本的模块,定义了涉及功能更改和扩充的插件位置。典型的框架例子有MFC框架和Struts框架。
在集中式计算技术时代广泛使用的是大型机/小型机计算模型。
20世纪80年代以后,集中式结构逐渐被以PC为主的微机网络所取代。个人计算机和工作站的采用,永远改变了大型机/小型机计算模型,从而产生了分布式计算模型。(协同计算、移动计算)
分布式计算模型主要具有以下优点:
客户机/服务器(client/server,C/S)体系结构是基于资源不对等,且为实现共享而提出来的,由服务器、客户机和网络三部分组成。
在C/S体系结构中,客户机可以通过远程调用来获取服务器提供的服务,因此,客户机必须知道可用的服务器的名字及它们所提供的服务,而服务器不需要知道客户机的身份,也不需要知道有多少台服务器在运行。
传统的C/S体系结构分为两层。在这种体系结构中,一个应用系统被划分为客户机和服务器两部分。典型的两层C/S体系结构如下图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MKQ8jv47-1623381971557)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210610083950570.png)]
两层C/S体系结构可以有两种形态:
(1)瘦客户机模型。在瘦客户机模型中,数据管理部分和应用逻辑都在服务器上执行,客户机只负责表示部分。瘦客户机模型的主要缺点:
(2)胖客户机模型。在这种模型中,服务器只负责对数据的管理。客户机上的软件实现应用逻辑和与系统用户的交互。
胖客户机模型能够利用客户机的处理能力,比瘦客户机模型在分布处理上更有效。但另一方面,随着企业规模的日益扩大,软件的复杂程度不断提高,胖客户机模型逐渐暴露出了以下缺点:
为了解决以上问题,三层C/S体系结构应运而生。三层C/S体系结构中增加了应用服务器。可以将整个应用逻辑驻留在应用服务器上,而只有表示层存在于客户机上。
三层C/S体系结构将整个系统分成表示层、应用逻辑层和数据层三个部分,其数据处理流程如下图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZTonYfCg-1623381971557)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210610084425027.png)]
(1)表示层:表示层是应用系统的用户界面部分,担负着用户与应用程序之间的对话功能。它用于检查用户从键盘等输入的数据,显示应用程序输出的数据,一般采用图形用户界面(graphic user interface, GUI)。
(2)应用逻辑层:应用逻辑层为应用系统的主体部分,包含具体的业务处理逻辑。通常在功能层中包含有确认用户对应用和数据库存取权限的功能以及记录系统处理日志的功能。
(3)数据层:数据层主要包括数据的存储及对数据的存取操作,一般选择关系型数据库管理系统(RDBMS)。
浏览器/服务器(browser/server,B/S)风格是三层体系结构的一种实现方式,其具体结构为浏览器/Web服务器/数据库服务器。B/S体系结构如下图所示。***(B/S是C/S的一种实现)***
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HXhQQve9-1623381971558)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210610085559608.png)]
B/S体系结构主要是利用不断成熟的WWW浏览器技术,结合浏览器的多种脚本语言,用通用浏览器就实现了原来需要复杂的专用软件才能实现的强大功能,并节约了开发成本。从某种程度上来说,B/S结构是一种全新的软件体系结构。
B/S体系结构具有以下优点:
(1)基于B/S体系结构的软件,系统安装、修改和维护全 在服务器端解决。
(2)B/S体系结构还**提供了异种机、异种网、异种应用服务的联机、联网和统一服务的最现实的开放性基础**。
与C/S体系结构相比,B/S体系结构也有许多不足之处。
(1)B/S体系结构缺乏对动态页面的支持能力,没有集成有效的数据库处理功能。
(2)采用B/S体系结构的应用系统,在数据查询等响应速度上,要远远地低于C/S体系结构。
(3)B/S体系结构的数据提交一般以页面为单位,数据的动态交互性不强,不利于在线事务处理(OLTP)应用。
问题:某企业在信息化的过程中,各个部门都建立了自己的管理系统,但信息没有得到共享。公司决定把各部门的管理系统加以集成,采用B/S体系结构统一管理。请绘制B/S体系结构的原理图,简述B/S结构的优点。
C/S 一般建立在专用的网络上, 小范围里的网络环境, 局域网之间再通过专门服务器提供连接和数据交换服务。
B/S 建立在广域网之上的, 不必是专门的网络硬件环境,例与电话上网, 租用设备. 信息自己管理. 有比C/S更强的适应范围, 一般只要有操作系统和浏览器就行
C/S 一般面向相对固定的用户群, 对信息安全的控制能力很强. 一般高度机密的信息系统采用C/S 结构适宜. 可以通过B/S发布部分可公开信息.
B/S 建立在广域网之上, 对安全的控制能力相对弱, 可能面向不可知的用户。
C/S 程序可以更加注重流程, 可以对权限多层次校验, 对系统运行速度可以较少考虑.
B/S 对安全以及访问速度的多重的考虑, 建立在需要更加优化的基础之上. 比C/S有更高的要求 B/S结构的程序架构是发展的趋势, 从MS的.Net系列的BizTalk 2000 Exchange 2000等, 全面支持网络的构件搭建的系统. SUN 和IBM推的JavaBean 构件技术等,使 B/S更加成熟.
C/S 程序可以不可避免的整体性考虑, 构件的重用性不如在B/S要求下的构件的重用性好.
B/S 对的多重结构,要求构件相对独立的功能. 能够相对较好的重用.就入买来的餐桌可以再利用,而不是做在墙上的石头桌子
C/S 程序由于整体性, 必须整体考察, 处理出现的问题以及系统升级. 升级难. 可能是再做一个全新的系统
B/S 构件组成,方面构件个别的更换,实现系统的无缝升级. 系统维护开销减到最小.用户从网上自己下载安装就可以实现升级.
C/S 程序可以处理用户面固定, 并且在相同区域, 安全要求高需求, 与操作系统相关. 应该都是相同的系统
B/S 建立在广域网上, 面向不同的用户群, 分散地域, 这是C/S无法作到的. 与操作系统平台关系最小.
C/S 多是建立的Window平台上,表现方法有限,对程序员普遍要求较高
B/S 建立在浏览器上, 有更加丰富和生动的表现方式与用户交流. 并且大部分难度减低,减低开发成本.
C/S 程序一般是典型的中央集权的机械式处理, 交互性相对低
B/S 信息流向可变化, B-B B-C B-G等信息、流向的变化, 更像交易中心。
(B/S是C/S的一种实现)
理想状态下应该是**高内聚低耦合**的模块
模块间联系得越紧密,耦合性就越高,其模块独立性就越弱。
一个模块内部各个元素之间联系越紧密,则他的内聚性越高,他的模块独立性就会越强
提供一个接口用以创建一个相联系或相依赖的对象族,而无须指定它们的具体类。
例如,在创建可支持多种GUI标准(如Motif和Persentation Manager)的绘图用户界面工具包时,因为不同的GUI标准会定义出不同外观及行为的“用户界面组件”(widget),如滚动条、按钮、视窗等。为了能够囊括各种GUI标准,应用程序不能把组件写死,不能限制到特定GUI风格的组件类,否则日后很难换成其他GUI风格的组件。
解决方法是:先定义一个抽象类WidgetFactory(用斜体字区分抽象类),这个类声明了创建各种基本组件的接口,再逐一替各种基本组件定义相对应的抽象类,如 ScrollBar、Window等,让它们的具体子类来真正实现特定的GUI标准。
抽象工厂模式的结构如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XUv7olN6-1623381971558)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609222203487.png)]
a) 抽象工厂类(AbstractFactory):声明创建抽象产品对象的操作的接口。
b) 具体工厂类(ConcreteFactory):实现产生具体产品对象的操作。
c) 抽象产品类(AbstractProduct):声明一种产品对象的接口。
d) 具体产品类(ConcreteProduct):定义将被相应的具体工厂类产生的产品对象,并实现抽象产品类接口。
e) 客户(Client):仅使用由抽象工厂类和抽象产品类声明的接口。
在执行时,AbstractFactory将产品交给ConcreteFactory创建。
ConcreteFactory类的实例只有一个,专门针对某种特定的实现标准,建立具体可用的产品对象。
如果想要建立其他标准的产品对象,客户程序就得改用另一种ConcreteFactory。
用抽象工厂模式设计农场类。
分析:农场中除了像畜牧场一样可以养动物,还可以培养植物,如养马、养牛、种菜、种水果等,本实例必须用抽象工厂模式来实现。
本例用抽象工厂模式来设计两个农场,一个是韶关农场用于养牛和种菜,一个是上饶农场用于养马和种水果,可以在以上两个农场中定义一个生成动物的方法 newAnimal() 和一个培养植物的方法 newPlant()。对马类、牛类、蔬菜类和水果类等具体产品类,由于要显示它们的图像.所以它们的构造函数中用到了 JPanel、JLabel 和 ImageIcon 等组件,并定义一个 show() 方法来显示它们。客户端程序通过对象生成器类 ReadXML 读取 XML 配置文件中的数据来决定养什么动物和培养什么植物。其结构图如下所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0X5bwdft-1623381971559)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609221407298.png)]
一个类只有一个实例并提供一个访问它的全局访问点。该实例应在系统生存期中都存在。
例如,通常情况下,用户可以对应用系统进行配置,并将配置信息保存在配置文件中,应用系统在启动时首先将配置文件加载到内存中,这些内存配置信息应该有且仅有一份。应用单件模式可以保证Configure类只能有一个实例。服务端的配置文件一般包含 侦听端口,还有数据库的连接信息 ;客户端的配置文件一般包含 服务器的 ip地址,端口。(初始化文件)
单件模式的结构如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jDnXjej8-1623381971559)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609222334934.png)]
a) 单件(Singleton):能够创建它唯一的实例;同时定义了一个Instance操作,允许外部存取它唯一的实例。Instance是一个静态成员函数
(5) 协作:客户只能通过Singleton的Instance() 存取这唯一的实例。
**下面代码实现了单例模式。**单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。代码输出结果为:
单例模式!!!
请根据题目意思,将代码空缺部分填完整。
public class Singleton1{
//(1)在下面空白处补充此处代码:定义合法的单例对象
private Singleton1() {
//(2)在下面空白处,依据题目意思补充此处代码
}
public static Singleton1 **getInstance()** {
//(3)在下面空白处,依据题目意思补充此处代码
}
public Object readResolve() {
return instance;
}
public static void main(String args[]){
Singleton1 s1=Singleton1.getInstance();
}
}
要求:单例模式类中,唯一的单例对象取名为“instance”,请参见已经给出代码,在下面空白处将空缺代码补充完整。
//(1)
private static Singleton1 instance= new Singleton1();
//(2)
return Singleton1();
//(3)
return instance;
适配器模式将一个类的接口转换为客户期望的另一种接口,使得原本不匹配的接口而无法合作的类可以一起工作。
有时要将两个没有关系的类组合在一起使用,一种解决方案是修改各自类的接口,另一种办法是使用Adapter模式,在两种接口之间创建一个混合接口。
例如,设有一个图形编辑器,可画直线、多边形、文本等。它的接口定义成抽象类Shape,它的子类负责画各种图形。此外,还有一个外购的GUI软件包TextView,用于显示,但它没有Shape功能。
适配器模式有类适配器模式和对象适配器模式。类适配器可以通过多继承方式实现不同接口之间的相容和转换,如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sIUhjEwc-1623381971560)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609222054433.png)]
而一个对象适配器则依赖对象组合的技术实现接口的相容和转换,如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OsX93bjf-1623381971560)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609222110188.png)]
a) 目标(Target):定义客户使用的与应用领域相关的接口。
b) 客户(Client):与具有Target接口的对象合作。
c) 被匹配者(Adaptee):需要被转换匹配的一个已存在接口。
d) 适配器(Adapter):将Adaptee的接口与Target接口匹配。
客户调用Adapter对象的操作,然后Adapter的操作又调用Adaptee对象中负责处理相应请求的操作。
有一个 MediaPlayer 接口和一个实现了 MediaPlayer 接口的实体类 AudioPlayer。默认情况下,AudioPlayer 可以播放 mp3 格式的音频文件。
我们还有另一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的实体类。该类可以播放 vlc 和 mp4 格式的文件。
我们想要让 AudioPlayer 播放其他格式的音频文件。为了实现这个功能,我们需要创建一个实现了 MediaPlayer 接口的适配器类 MediaAdapter,并使用 AdvancedMediaPlayer 对象来播放所需的格式。
AudioPlayer 使用适配器类 MediaAdapter 传递所需的音频类型,不需要知道能播放所需格式音频的实际类。AdapterPatternDemo 类使用 AudioPlayer 类来播放各种格式。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WVCVYxQr-1623381971561)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609222512290.png)]
通过一条隐式的对象消息链传递处理请求。该请求沿着这条链传递,直到有一个对象处理它为止。其核心是避免将请求的发送者直接耦合到它的接受者。
以GUI系统的联机帮助系统为例。用户可以在软件中任一位置按下help键,软件就可以根据该信息和当前上下文环境弹出适当的说明。
如果用户在PrintDialog对话框里“打印”按钮上按了帮助键,帮助信息的顺序图如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-touFTWgU-1623381971561)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609222634511.png)]
联机帮助系统定义了一个抽象类HelpHandler和抽象操作HandleHelp(),所有想处理信息的类可以继承该类。HelpHandler的HandleHelp() 操作的内定做法是把信息传递给后继者去处理,由各个子类分别来实现具体的打印功能。如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zG5tUbpy-1623381971562)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609222651737.png)]
责任链模式的结构如图所示 。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IpJMBP31-1623381971562)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609222733978.png)]
典型的对象间的结构如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F7cES5CA-1623381971563)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609222754996.png)]
a) 处理者(Handler):定义处理请求的接口;实现对后继者的链接(可选)。
b) 具体处理者(ConcreteHandler):处理它所负责的请求;可访问它的后继;如果它能够处理请求,就处理该请求,否则将请求传送给后继者。
c) 客户(Client):将处理请求提交给职责链中的ConcreteHandler对象。
(5) 协作:当Client发出请求之后,请求会在责任链中传递,直到有一个ConcreteHandler对象能处理为止。
用一个中介对象来封装一系列复杂对象的交互情景。中介者通过阻止各个对象显式地相互引用来降低它们之间的耦合,使得人们可以独立地改变它们之间的交互。
以GUI系统的对话框为例,对话框中会布置许多窗口组件,如按钮、菜单、文字输入栏等。对话框中各窗口组件之间往往相互牵连。
为此,可以**将这些窗口组件的集体行为封装成一个中介者(mediator)对象。中介者负责居中指挥协调一组对象之间的交互行为,避免互相直接引用。**这些对象只认得中介者,因而可降低交互行为的数目。
例如,可用FontDialogDirector当作对话框内各窗口组件之间的中介者。FontDialogDirector对象认得所有组件,协调彼此之间的交互,如同一个通信枢纽,如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MN0jjFt6-1623381971564)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609223023495.png)]
图(a)给出了中介者的类结构,图(b)给出了典型的对象结构。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5pgc4oib-1623381971565)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609223102685.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y1fuuZr7-1623381971565)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609223107708.png)]
a) 中介者(Mediator):定义与各个同事(Colleague)对象通信的接口。
b) 具体中介者(ConcreteMediator):协调各个同事对象,实现协作行为;了解并维护各个同事对象。
c) 同事类(Colleague classes):这些同事类的对象都了解中介者;一个同事对象与另一个同事对象之间的通信都需要通过中介者来间接实现。
同事向中介者对象发送或接收请求,中介者则将请求传送给适当的同事对象(一个或多个),协调整体行为。
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知,并被自动更新。
例如,许多GUI软件包都将数据显示部分与应用程序底层的数据表示分开,以利于分别复用。但这些类也能合作,如图所示的计算表和直方图都是针对同一数据对象的两种不同表示方式。
Observer模式的结构如图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oVe1sDlT-1623381971566)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609223237970.png)]
a) 主题(Subject):认得它的观察者。任意数目的观察者对象均可订阅一个主题。另外,提供一个连接观察者对象和解除连接的接口。
b) 观察者(Observer):定义了一个自我更新的接口。一旦发现主题有变时借助接口通知自己随之改变。
c) 具体主题(ConcreteSubject):存储具体观察者对象关心的状态;当状态改变时向它的观察者发送通知。
d) 具体观察者(ConcreteObserver):维持一个对具体主题对象的引用;存储要与主题一致的状态;实现观察者的自我更新接口,确保自己的状态与主题的状态一致。
当具体主题发生会导致观察者的状态不一致的情况时,就会主动通知所有该通知的观察者。当具体观察者收到通知后,向主题询问,根据所得信息使自己的状态与主题的状态保持一致。下图给出了一个主题和两个观察者对象之间的交互情况。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WQ20Ll8I-1623381971566)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609223408844.png)]
在设计的初始阶段,系统设计师用系统环境图对软件与外部实体交互的方式进行建模。下图给出了系统环境图的一般的结构。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GjBK0YcN-1623381971567)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210610172144138.png)]
体系结构设计可以自底向上进行,如将关系紧密的对象组织成子系统或层;也可以自顶向下进行,尤其是使用设计模式或遗产系统时,会从子系统的划分入手。
对于面向对象的系统,典型的子系统有问题域子系统、人机交互子系统和任务管理子系统。
对象设计以问题领域的对象设计为核心,其结果是一个详细的对象模型。对象设计过程包括使用模式设计对象、接口规格说明、对象模型重构、对象模型优化4组活动。
传统的面向过程方法中的模块通常是函数、过程及子程序等,而面向对象方法中的模块则是类、对象、接口、构件等。
在面向过程的方法中,数据及在数据上的处理是分离的;而在面向对象方法中,数据及其上的处理是封装在一起的,具有更好的独立性,也能够更好地支持复用。
面向对象方法不仅支持过程抽象,而且支持数据抽象。类实际上就是一种抽象数据类型。可以将类的抽象分为规格说明抽象及参数化抽象。
类对外开放的公共接口构成了类的规格说明,即协议。这种接口规定了外部可以使用的服务,使用者无需知道这些服务的具体实现算法。通常将这类抽象称为规格说明抽象。
参数化抽象是指当描述类的规格说明时并不具体指定所要操作的数据类型,而是将数据类型作为参数。
在面向对象方法中,信息隐藏通过对象的封装性实现。对于类的用户来说,属性的表示方法和操作的实现算法都应该是隐藏的。
耦合是指一个软件结构内不同模块之间互连的紧密程度。在面向对象方法中,对象是最基本的模块,因此,耦合主要指不同对象之间相互关联的紧密程度。
内聚衡量一个模块内各个元素彼此结合的紧密程度。在面向对象设计中存在以下3种内聚:
软件重用是提高软件开发生产率和目标系统质量的重要途径。
重用基本上从设计阶段开始。重用有两方面的含义:
在选择编程语言时,可以考虑以下因素。
有些软件开发部门对序言性注释做了明确而严格的规定,要求程序编制者逐项列出。
功能性注释嵌在源程序体中,用以描述其后的语句或程序段,也就是解释下面要“做什么”,或是执行了下面的语句会怎么样。
例如,下面的注释行仅仅重复了后面的语句,对于理解它的工作并没有什么作用。
/* Add amount to total */
total = amount+total;
如果注明把月销售额计入年度总额,便使读者理解了下面语句的意图:
/* Add monthly-sales to annual-total */ total = amount+total;
白盒测试分为静态白盒测试和动态白盒测试。
通过评审文档和阅读代码等方式测试软件。可以利用专门的静态测试工具分析代码中的缺陷,也可以人工去测试,但静态测试对测试人员的编码和测试等水平要求很高。
常用的动态白盒测试方法有逻辑覆盖法、基本路径测试法等。
以程序内部的逻辑结构为基础设计测试用例的方法。
语句覆盖是一个比较弱的测试标准,它的含义是:选择足够的测试用例,使得程序中每个语句至少都能被执行一次。
float M (float A,float B,float X){
if ((A>1) && (B==0)) X=X/A;
if ((A==2) || (X>1)) X=X+1;
return X;
}
为使程序中每个语句至少执行一次,只需设计一个能通过路径ace的例子就可以了,例如选择输入数据为:
A=2,B=0,X=3
就可达到“语句覆盖”标准。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dly4FYqw-1623381971568)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609225724546.png)]
void DoWork(int x,int y,int z){
int k=0,j=0;
if((x>3)&&(z<10)) {
k=x*y-1; //语句块1
j=sqrt(k); }
if((x= =4)||(y>5)) {
j=x*y+10; //语句块2}
j=j%3; //语句块3}
为了测试语句覆盖率只要设计一个测试用例就可以把三个执行语句块中的语句覆盖了。测试用例输入为:
x=4、y=5、z=5
程序执行的路径是:abd
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FVFeMjlp-1623381971568)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609225926544.png)]
一般认为“语句覆盖”是很不充分的一种标准,是最弱的逻辑覆盖准则。
执行足够的测试用例,使得程序中的每一个判定取真分支和取假分支至少都通过一次。
对例1的程序,如果设计两个例子,使它们能通过路径ace和abd,或者通过路径acd和abe,就可达到“判定覆盖”标准,为此,可以选择输入数据为:
① A=3,B=0,X=1 (沿路径acd执行); ② A=2,B=1,X=3(沿路径abe执行)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ruN3FjTK-1623381971569)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609230121189.png)]
对于例2的程序,如果设计两个测试用例则可以满足条件覆盖的要求。
测试用例的输入为:
x=4、y=5、z=5x=2、y=5、z=5
上面的两个测试用例虽然能够满足条件覆盖的要求,但是也不能对判断条件进行检查,例如把第二个条件y>5错误的写成y<5,、上面的测试用例同样满足了判定覆盖。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2NQhRAEl-1623381971571)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609230224516.png)]
往往大部分的判定语句是由多个逻辑条件组合而成,若仅仅判断其整个最终结果,而忽略每个条件的取值情况,必然会遗漏部分测试路径。
执行足够的测试用例,使得判定中的每个条件的可能取值至少满足一次。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P2aqQHnt-1623381971571)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609230527984.png)]
测试用例 | 通过路径 | 条件取值 | 覆盖分支 |
---|---|---|---|
x=4、y=6、z=5 | abd | T1、T2、T3、T4 | bd |
x=2、y=5、z=5 | ace | F1、T2、F3、F4 | ce |
x=4、y=5、z=15 | acd | T1、F2、T3、F4 | cd |
“条件覆盖”通常比“判定覆盖”强,因为它使一个判定中的每一个条件都取到了两个不同的结果,而判定覆盖则不保证这一点。
“条件覆盖”并不包含“判定覆盖”,如对语句IF(A AND B)THEN S 设计测试用例使其满足"条件覆盖",即使A为真并使B为假,以及使A为假而且B为真,但是它们都未能使语句S得以执行。
执行足够的测试用例,使得分支中每个条件取到各种可能的值,并使每个分支取到各种可能的结果。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lDW9COvx-1623381971572)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609230933896.png)]
测试用例 | 通过路径 | 条件取值 | 覆盖分支 |
---|---|---|---|
x=4、=6、z=5 | abd | T1、T2、T3、T4 | bd |
x=2、y=5、z=11 | ace | F1、F2、F3、F4 | ce |
分支/条件覆盖从表面来看,它测试了所有条件的取值,但是实际上某些条件掩盖了另一些条件。
执行足够的例子,使得每个判定中条件的各种可能组合都至少出现一次。
满足“条件组合覆盖”的测试用例是一定满足“分支覆盖”、“条件覆盖”和“分支/条件覆盖”的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eskAIPDT-1623381971573)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609231211189.png)]
测试用例 | 通过路径 | 条件取值 | 覆盖组合号 |
---|---|---|---|
x=4、y=6、z=5 | abd | T1、T2、T3、T4 | 1和5 |
x=4、y=5、z=15 | acd | T1、F2、T3、F4 | 2和6 |
x=2、y=6、z=5 | acd | F1、T2、F3、T4 | 3和7 |
x=2、y=5、z=15 | ace | F1、F2、F3、F4 | 4和8 |
上面的测试用例覆盖了所有条件的可能取值的组合,覆盖了所有判断的可取分支,但是却丢失了一条路径abe。
设计足够多的测试用例,覆盖被测试对象中的所有可能路径。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gKuKZ6Je-1623381971573)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609231358953.png)]
测试用例 | 通过路径 | 覆盖条件 |
---|---|---|
x=4、y=6、z=5 | abd | T1、T2、T3、T4 |
x=4、y=5、z=15 | acd | T1、F2、T3、F4 |
x=2、y=5、z=15 | ace | F1、F2、F3、T4 |
x=5、y=5、z=5 | abe | T1、T2、F3、F4 |
基本路径测试就是在程序控制图的基础上,通过分析控制构造的环行复杂性,导出基本可执行路径集合,从而设计测试用例的方法。设计出的测试用例要保证在测试中程序的每一个可执行语句至少执行一次。
测试进入的前提条件是在测试人员已经对被测试对象有了一定的了解,基本上明确了被测试软件的逻辑结构。
过程是通过针对程序逻辑结构设计和加载测试用例,驱动程序执行,以对程序路径进行测试。测试结果是分析实际的测试结果与预期的结果是否一致。
在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例。包括以下4个步骤和一个工具方法:
图形矩阵:是在基本路径测试中起辅助作用的软件工具,利用它可以实现自动地确定一个基本路径集。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5f7mzin5-1623381971574)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609231753444.png)]
至少沿一条新的边移动的路径
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lKxx5prS-1623381971575)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609231844684.png)]
流程图用来描述程序控制结构。可将流程图映射到一个相应的流图(假设流程图的菱形决定框中不包含复合条件)。在流图中,每一个圆,称为流图的结点,代表一个或多个语句。一个处理方框序列和一个菱形决测框可被映射为一个结点,流图中的箭头,称为边或连接,代表控制流,类似于流程图中的箭头。一条边必须终止于一个结点,即使该结点并不代表任何语句(例如:if-else-then结构)。由边和结点限定的范围称为区域。计算区域时应包括图外部的范围。
例4:有下面的C函数,用基本路径测试法进行测试
void Sort(int iRecordNum,int iType) { int x=0; int y=0; while (iRecordNum-- > 0) { if(0= =iType) { x=y+2; break;} else if (1= =iType) x=y+10; else x=y+20; } }
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xT3MvA5J-1623381971576)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609232113089.png)]
环路复杂度是一种为程序逻辑复杂性提供定量测度的软件度量,将该度量用于计算程序的基本的独立路径数目,为确保所有语句至少执行一次的测试数量的上界。独立路径必须包含一条在定义之前不曾用到的边。
有以下三种方法计算环路复杂度:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uu6tXYGp-1623381971576)(C:\Users\cxn81\AppData\Roaming\Typora\typora-user-images\image-20210609232326195.png)]
对应上面图中的环路复杂度,计算如下:
根据上面的计算方法,可得出四个独立的路径。(一条独立路径是指,和其他的独立路径相比,至少引入一个新处理语句或一个新判断的程序通路。V(G)值正好等于该程序的独立路径的条数。)
路径1:4-14
路径2:4-6-7-14
路径3:4-6-8-10-13-4-14
路径4:4-6-8-11-13-4-14
根据上面的独立路径,去设计输入数据,使程序分别执行到上面四条路径。
void Sort(int iRecordNum,int iType) { int x=0; int y=0; while (iRecordNum-- > 0) { if(0= =iType) {x=y+2; break;} else if(1= =iType) x=y+10; else x=y+20; } }
为了确保基本路径集中的每一条路径的执行,根据判断结点给出的条件,选择适当的数据以保证某一条路径可以被测试到,满足上面例子基本路径集的测试用例是:
路径1:4-14
输入数据:iRecordNum=0,或者
取iRecordNum<0的某一个值
预期结果:x=0
路径2:4-6-7-14
输入数据:iRecordNum=1,iType=0
预期结果:x=2
路径3:4-6-8-10-13-4-14
输入数据:iRecordNum=1,iType=1
预期结果:x=10
路径4:4-6-8-11-13-4-14
输入数据:iRecordNum=1,iType=2
预期结果:x=20
黑盒测试是测试人员完全不考虑程序内部的逻辑结构和内部特性,只依据程序需求规格说明书,检查程序的功能是否符合他的功能需求的测试方法
注重于测试软件界面和功能需求
依据需求对输入的范围进行细分,然后再分出的每一个区域内选取一个有代表性的测试数据开展测试。
在某网站申请免费信箱时,要求用户必须输入用户名、密码及确认密码,对每一项输入条件的要求如下:
用户名要求为4位以上,16位以下,使用英文字母、数字、“-”、“”,并且首字符必须为字母或数字;密码要求为6~16位之间,只能使用英文字母、数字以及“-”、“”,并且区分大小写。
分析如下:
分析程序的规格说明,列出等价类表(包括有效等价类和无效等价类)
输入条件 | 有效等价类 | 编号 | 无效等价类 | 编号 |
---|---|---|---|---|
用户名 | 4~16位 | 1 | 少于4位 | 8 |
多于16位 | 9 | |||
首字符为字母 | 2 | 首字符为除字母、数字之外的其他字符 | 10 | |
首字符为数字 | 3 | |||
英文字母、数字、“-”、“_”组合 | 4 | 组合中含有除英文字母、数字、“-”、“_”之外的其他特殊字符 | 11 | |
密码 | 6~16位 | 5 | 少于6位 | 12 |
多于16位 | 13 | |||
英文字母、数字、“-”、“_”组合 | 6 | 组合中含有除英文字母、数字、“-”、“_”之外的其他特殊字符 | 14 | |
确认密码 | 内容同密码相同 | 7 | 内容同密码相同,但字母大小写不同 | 15 |
根据上述等价类表,设计测试用例如表所示。
测试用例 | 用户名 | 密码 | 确认密码 | 预期输出 |
---|---|---|---|---|
TC1 | abc_2000 | abc_123 | abc_123 | 注册成功 |
TC2 | 2000-abc | 123-abc | 123-abc | 注册成功 |
TC3 | abc | 12345678 | 12345678 | 提示用户名错误 |
TC4 | abcdefghijk123456 | 12345678 | 12345678 | 提示用户名错误 |
TC5 | _abc123 | 12345678 | 12345678 | 提示用户名错误 |
TC6 | abc&123 | 12345678 | 12345678 | 提示用户名错误 |
TC7 | abc_123 | 12345 | 12345 | 提示密码错误 |
TC8 | abc_123 | abcdefghijk123456 | abcdefghijk123456 | 提示密码错误 |
TC9 | abc_123 | abc&123 | abc&123 | 提示密码错误 |
TC10 | abc_123 | abc_123 | Abc_123 | 提示密码错误 |
对**输入或输出的边界值进行测试**的一种黑盒测试方法。通常边界值分析法是作为对等价类划分法的补充,这种情况下,其测试用例自然来自于等价类的边界。
数据范围是1<=x<=50正整数
边界值取为:1、50、0、51
数据范围是1 边界值取为:1、50、2、49 输入文件名介于file0101~file0120之间 边界值取为file0100,file0101,file0120,file0121 边界值分析使用与等价类划分法相同的划分,只是**边界值分析假定错误更多地存在于划分地边界上,因此在等价类的边界上以及两侧**情况设计用例 软件维护是指在软件运行/维护阶段对软件产品所进行的修改就是所谓的维护。根据维护工作的性质,软件维护的活动可以分为以下4种类型。 改正性维护(corrective maintenance)为了识别和纠正软件错误、改正软件性能上的缺陷、排除实施中的误使用,应进行的诊断和改正错误的过程。例如,改正性维护可以是改正原来程序中开关使用的错误;解决开发时未能测试各种可能情况带来的问题等。 随着信息技术的飞速发展,软件运行的外部环境(新的硬、软件配置)或数据环境(数据库、数据格式、数据输入 为了满足新的功能与性能要求,需要修改或再开发软件,以扩充软件功能、增强软件性能、改进加工效率、提高软件的可维护性。这种情况下进行的维护活动叫做完善性维护(perfective maintenance)。例如,完善性维护可能是修改一个计算工资的程序,使其增加新的扣除项目;缩短系统的应答时间,使其达到特定的要求等。 预防性维护(preventive maintenance)是指把今天的方法学用于昨天的系统以满足明天的需要。也就是说,采用先进的软件工程方法对需要维护的软件或软件中的某一部分(重新)进行设计、编码和测试。 由于软件具有可见性差、定量化难等特殊性,因此很难在项目完成前准确地估算出开发软件所需的工作量和费用。通常我们可以根据以往开发类似软件的经验(也可以是别人的经验)来进行成本估算。也可以将软件项目划分成若干个子系统或按照软件生存周期的各个阶段分别估算其成本,然后汇总出整个软件的成本。此外还可以使用经验公式和成本估算模型来进行估算。 一种常用的成本估算方法是先估计完成软件项目所需的工作量(人月数),然后根据每个人月的代价(金额)计算软件的开发费用: 开发费用=人月数×每个人月的代价 另一种方法是估计软件的规模(通常指源代码行数),然后根据每行源代码的平均开发费用(包括分析、设计、编码、测试所花的费用),计算软件的开发费用: 开发费用=源代码行数×每行平均费用 估算源代码行数时,请几位有经验的专家,每位专家对软件给出3个估计值: b i — — 最 大 代 码 行 数 ( 该 软 件 可 能 的 最 大 规 模 ) bi——最大代码行数(该软件可能的最大规模) bi——最大代码行数(该软件可能的最大规模) m i — — 最 可 能 的 代 码 行 数 ( 该 软 件 最 可 能 的 规 模 ) mi——最可能的代码行数(该软件最可能的规模) mi——最可能的代码行数(该软件最可能的规模) 然后计算出每位专家的估算期望值Ei 功能点方法克服了项目开始时无法准确得知源程序行数的实际困难,从软件产品的功能度出发估算出软件产品的规模。 功能点方法是以项目的需求规格说明中已经得到确认的软件功能为依据,着重分析要开发系统的功能度。并且认为,软件的大小与软件的功能度相关。而与软件功能如何描述无关,也与功能需求如何设计和实现无关。 软件功能除了上述分类以外,**每类功能都有简单和复杂之分,及功能的复杂程度有所不同。**为表面功能复杂的差别,将其分为简单、中等和复杂三个等级。同时为标识其差异程度,分别赋予不同的影响参数。 某一个软件,只要我们能够从规格说明中得到以上5种功能度的各级复杂功能点的个数C,不难计算出未调节功能点的值。 任何软件都会有自身特性,在考虑其各个自身特性时,从两个方面分解功能点计算的调节因子。 复杂调节因子 经过调节因子调节后的功能点值被称为交付功能点 一些研究成果表明,上述计算出的功能点的值可以代表软件规模,也可以作为估算成本的依据。 (见课本P314页)
技巧
8、维护
改正性维护
适应性维护
/输出方式、数据存储介质)可能发生变化,为了使软件适应这种变化,而修改软件的过程叫做适应性维护(adaptive maintenance)。例如,需要对已运行的软件进行改造,以适应网络环境或已升级改版的操作系统要求。完善性维护
预防性维护
9、成本计算
(1)代码行(专家判定——Delphi方法)
a i — — 最 少 源 代 码 行 数 ( 该 软 件 可 能 的 最 小 规 模 ) ai——最少源代码行数(该软件可能的最小规模) ai——最少源代码行数(该软件可能的最小规模)
E i = ( a i + 4 m i + b i ) / 6 Ei=(ai+4mi+bi)/6 Ei=(ai+4mi+bi)/6
估算值的期望中值E
E = 1 / n ∑ E i E=1/n∑Ei E=1/n∑Ei(2)功能点
功能度
5种类型的功能
功能复杂度
未调节功能点
调节因子
C A F = 0.65 + 0.01 N CAF=0.65+0.01N CAF=0.65+0.01N交付功能点
D F P = C A F × U F P DFP=CAF×UFP DFP=CAF×UFP交付功能点与软件规模
功能点方法的优点
功能点方法的不足之处
*功能点方法计算实例
10、计划进度管理
(1)关键路径
(2)网络图