一.软件工程概述
名词解释部分考点
软件危机:在计算机软件开发和维护过程中所遇到的一系列严重问题。主要包含两个方面:如何开发软件,以满足日益增长的软件需求;如何维护数量不断膨胀的已有软件
软件工程:采用工程的概念、原理、技术和方法来开发与维护软件,把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来,经济的开发出高质量的软件并维护它
软件过程:是为了获得高质量软件所需要完成的一系列任务框架,它规定了完成任务的工作步骤。通常用软件生命周期模型来描述软件过程
软件危机
(简答)什么是软件危机,其产生的原因是什么 :
软件危机是在计算机开发和维护过程中所遇到的一系列的严重问题,主要包含两个方面
如何开发软件,以满足日益增长的软件需求
如何维护软件数量不断膨胀的已有软件软件危机的原因
①:主观方面
忽视需求分析
轻视软件维护
没有认识到程序只是软件的一部分
没有认识到开发只是软件漫长生命周期中一个比较次要的阶段
越到后期引入变动代价会越高②:客观方面
软件是逻辑实体,具有不可见性,管理控制很困难
软件不会磨碎,维护意味着需要原来的设计,维护困难
软件规模庞大,程序的复杂性会随着软件规模增加而增加
软件工程
采用工程的概念、原理、技术和方法来开发与维护软件,把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来,经济的开发出高质量的软件并维护它
软件工程方法学
三要素:方法,工具,过程
软件生命周期
软件生命周期阶段如何划分?(考点)
软件定义该时期有三个阶段
问题定义:弄清用户要解决什么问题可行性研究:确定问题是否可行
需求分析:为了解决这个问题,系统需要具备怎样的功能
软件开发
该时期有四个阶段
总体设计:设计软件结构,确定程序由哪些模块组成以及模块间的关系详细设计:针对每个模块,设计详细规格说明,确定算法和数据结构
编码和单元测试:将详细设计内容用语言实现,并测试每个模块
综合测试:通过各种类型测试使软件达到预定要求
软件维护
①改正性维护,即诊断和改正在使用过程中发现的软件错误;
②适应性维护,即修改软件以适应环境的变化;
③完善性维护,即根据用户的要求改进或扩充软件使它更完善;
④预防性维护,即修改软件,为将来的维护活动预先做准备。
软件过程
瀑布模型:将软件生命周期的各项活动规定为依照固定顺序连接的若干阶段工作,最终得到软件产品
特点
①阶段间具有顺序性和依懒性
必须等前一阶段的工作完成之后,才能开始后一阶段的工作;
前一阶段的输出文档是后一阶段的输入文档
只有前一阶段的输出文档正确,后一阶段的工作才能获得正确的结果
②推迟实现的观点
瀑布模型在编码之前设置了系统分析与系统设计的各个阶段,分析与设计阶段的基本任务规定,在这两个阶段主要考虑目标系统的逻辑模型,不涉及软件的物理实现。
清楚地区分逻辑设计与物理设计,尽可能推迟程序的物理实现,是按照瀑布模型开发软件的一-条重要的指导思想。
③质量保证的观点
为了保证所开发的软件的质量,在瀑布模型的每个阶段都必须完成规定的文档,没有交出合格的文档就是没有完成该阶段的任务。
完整、准确的合格文档不仅是软件开发时期各类人员之间相互通信的媒介,也是运行时期对软件进行维护的重要依据。
越是早期阶段犯下的错误,暴露出来的时间就越晚,排除故障改正错误所需付出的代价也越高。
因此,及时审查,是保证软件质量、降低软件成本的重要措施。每个阶段结束前都要对所完成的文档进行评审,以便尽早发现问题,改正错误。
优点:
强迫开发人员使用规范的方法
严格规定了每个阶段提交的文档
要求每个阶段交出的产品都必须经过质量保证小组的验证
对文档的约束,使得软件维护变得容易一些,且能降低软件预算缺点
在软件开发初期就要求做出正确的,全面的,完整的需求分析对多数应用软件来说是很困难的
在需求分析阶段,在需求确定后,无法及时验证需求是否正确,完整
作为整体开发的瀑布模型,由于不支持产品演化,缺乏灵活性,对开发过程中很难发现的错误,只有在产品最终运行时才能发现
适用范围
用户的需求非常清晰全面,且在开发过程中没有或很少有变化
开发人员对软件的应用领域很熟悉
用户的使用环境非常稳定
开发工作对用户的参与要求很低
快速原型模型:快速建立可运行的程序,它完成的功能往往是最终产品功能的一个子集
原理:快速原型模型的第一步是快速建立一个能反映用户主要需求的原型系统,让用户通过实践来了解目标系统的概貌。通常,用户试用原型系统之后会提出许多修改意见,开发人员按照用户的意见快速地修改原型系统,然后再次请用户试用,一旦用户认为这个原型系统确实能做他们所需要的工作,开发人员便可据此书写规格说明文档,根据这份文档开发出的软件便可以满足用户的真实需求。
优点:
开发的软件通常满足用户需求
软件开发基本是线性过程
缺点
准确原型设计困难
原型理解可能不同
不利于开发人员创新
适用范围
对所开发的领域比较熟悉且与快速的原型开发工具
项目招投标时,可以以原型模型作为软件的开发模型
进行产品移植或升级时,或对已有产品原型进行客户化工作时
增量模型:先完成一个系统子集的开发,再按同样的开发步骤增加功能,如此递增下去直至满足全部系统需求
优点
短时间内可提交部分功能
逐渐增加产品功能,用户适应产品快以组件为单位进行开发降低了软件开发的风险。一个开发周期内的错误不会影响到整个软件系统
缺点
增量构件划分及集成困难
容易退化成边做边改模型
适用范围
增量模型适用于那些需求变化频繁、开发周期较长、需要快速交付、项目规模大,需要不断迭代和更新的项目。在这种情况下,增量模型能够帮助开发团队更好地控制项目进度,降低开发风险,提高项目的成功率和用户满意度。
螺旋模型:在每个阶段之前都增加了风险分析过程的快速原型模型
适用范围
螺旋模型强调风险分析,但要求许多客户接受和相信这种分析,并做出相关反应是不容易的,因此,这种模型往往适应于内部的大规模软件开发
喷泉模型:典型的面向对象软件过程模型。体现了迭代和无缝的特性
优点
利于把软件质量作为软件的开发目标
减少测试
维护和开发不分开
缺点
风险估计困难
适用范围
适应于面向对象的软件开发过程。
敏捷开发是一种以人为核心,以迭代方式循序渐进开发的方法,其软件开发的过程称为“敏捷过程”
以代码为核心
以人为本、循环迭代、响应变化
适用范围
总的来说,敏捷过程适用于那些需要快速响应变化、强调迭代开发和持续反馈、需要灵活性和自组织团队等情况。
二.可行性研究
可行性研究概念
可行性研究的目的:用最小的代价在最小的时间内确定问题是否可以被解决
可行性研究的本质:系统分析和设计过程的大大压缩和简化,在较高层次上以较为抽象的方式进行系统的分析和设计过程
可行性研究的任务:
可行性研究的最根本任务:对以后的行动方针提出建议
具体任务:
1.分析和澄清问题的定义
2.导出系统的逻辑模型
数据流图+数据字典
3.根据逻辑模型探索若干种可供选择的解法
4.研究每种解法的可行性
经济可行性:经济效益是否大于开发成本
技术可行性:现有技术能够实现
操作可行性:系统操作方式是否可行
其它可行性:法律、社会效益
名词解释
- 数据流图:描述信息流和数据从输入到输出所经受的变换。没有任何具体物理部件,只是描绘数据在软件中流动和被处理的逻辑过程
- 数据字典:是关于数据的信息集合,即对数据流图中包含的所有元素定义的集合,在软件分析和设计的过程中给人提供关于数据的描述信息
- 数据流图和数据字典共同构成系统的逻辑模型
数据流图
数据流图示例
假设一家工厂的采购部每天需要一张订货报表,报表按零件编号排序,表中列出所有需要再次订货的零件。对于每个需要再次订货的零件应该列出下述数据:零件编号,零件名称,订货数量,目前价格,主要供应者,次要供应者。零件入库或出库称为事务,通过放在仓库中的CRT终端把事务报告给订货系统。当某种零件的库存数量少于库存量临界值时就应该再次订货。画出上述订货系统的数据流图
A:首先从题目中提取四种成分
1:考虑数据的源点和终点
数据源点:仓库管理员
数据终点:采购员
2:考虑有哪些处理
“采购部需要报表”,所以需要一个产生报表的处理
仓库中的零件数量会发生改变,所以对事物进行的加工是另一个处理
3:考虑数据流
系统会把订货报表送给采购部,所以订货报表是一个数据流
事物需要从仓库送到系统中,所以事物是一个数据流
4:考虑数据存储
每当有一个事物发生时就应该立即处理,但是由于每天只产生一次订货报表。因此用于产生订货报表的数据必须存放一段时间,所以有一个数据存储
画数据流图
2:细化模型,描绘系统主要功能
产生报表和处理事物是系统必须完成的两个主要功能
细化后增加了两个数据存储:处理事物需要库存清单数据;产生报表和处理事物需要订货信息
3:进一步细化功能级数据流图中描绘的系统主要功能
当一个事物发生使必须先接受它,随后按照事物的内容修改库存清单,最后如果更新后的库存量少于临界值,需要再次订货
数据字典
数据字典应该由对下列4类元素的定义组成
数据流
数据元素
数据存储
处理
三:定义数据的方法
(1)数据元素组成数据的方式
顺序
选择
重复
可选
(2)符号表示
=的意思是等价于
+的意思是和(即连接两个分量)
[]的意思是或(即从括号内的分量中选择一个)
|的意思是隔开供选择的分量
{}的意思是重复
()的意思是可选(即括号内的分类可有可无)
四:数据字典示例
北京某高校可用的电话号码有以下几类:校内电话号码由4位数字组成,第一位数字不是0。校外电话又分为本市电话和外地电话两类。拨校外电话需要先拨0,若是本市电话则接着拨8位数字(第一位不是0),若是外地电话则拨3位区码后再拨8位电话号码(第一位不是0)
电话号码=[校内电话 | 校外电话]
校内电话=非零数字+三位数字
非零数字=[ 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ]
三位数字=3{数字}3
数字=[ 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ]
校外电话=[本市电话 | 外地电话]
本市电话=0 + 八位非零开头数字
八位非零开头数字=非零数字+七位数字
七位数字=7{数字}7
外地电话=0 + 三位区码 + 八位非零开头数字
三位区码=三位数字
三.需求分析
概念
为什么要进行需求分析,对软件系统的要求?
需求分析的定义:需求分析是软件定义时期的最后一个阶段,它的基本任务是准确地回答“系统必须做什么”这个问题,目标系统提出完整、准确、清晰、具体的要求。在需求分析阶段结束之前,系统分析员应该写出软件需求规格说明书,以书面形式准确地描述软件需求
需求分析的必要性:为了开发出真正满足用户需求的软件产品,首先必须要知道用户的需求。对软件需求的深入理解是软件开发工作获得成功的必要前提,不论人们把设计和编码工作做得如何出色,不能满足用户需求的程序只会让用户失望
软件系统需求
功能要求
性能要求
可靠性和可用性要求
出错处理需求
接口需求
约束
逆向需求
将来可能提出需求
- 必须理解并描述问题的信息域,根据这条准则应该建立数据模型
- 必须定义软件应完成的功能,这条准则要求建立功能模型
- 必须描述作为外部事件结果的软件行为,这条准则要求建立行为模型
- 必须对描述信息、功能和行为的模型进行分解,用层次的方式展示细节
步骤
- 需求获取
- 分析建模
- 需求描述
- 需求验证
结构化分析的图形工具
1、层次方框图
2、Warnier图
四.总体设计
总体设计的相关概念
总体设计的任务:确定系统中每个程序是由哪些模块组成的,以及这些模块相互间的关系
总体设计的必要性:可以站在全局高度上,花较少成本,从较抽象的层次上分析对比多种可能的系统实现方案和软件结构,从中选出最佳方案和最合理的软件结构,从而用较低成本开发出较高质量的软件系统
软件设计的原则
1、模块化(高内聚低耦合)
2、抽象
3、逐步求精
4、信息隐藏
名词解释
模块:模块是由边界元素限定的相邻程序元素所组成的序列,而且有一个总体标识符代表它。模块是构成程序的基本构件
模块化:模块化就是把程序划分成独立命名且可独立访问的模块,每个模块完成一个子功能,把这些模块集成起来构成一个整体,可以完成指定的功能以满足用户的需求
模块独立性:开发具有独立功能而且和其他模块之间没有过多的相互作用的模块,就可以做到模块独立。独立的模块比较容易测试和维护
抽象:抽出事物的本质特性而暂时不考虑它们的细节
逐步求精:逐步求精是软件工程技术的基础,为了能集中精力解决主要问题而尽量推迟对问题细节的考虑
信息隐藏:指一个模块内包含的信息对于不需要这些信息的模块来说是不能访问的,主要是指模块的实现细节
局部化:指把一些关系密切的软件元素物理地放得彼此接近,有助于实现信息隐藏
耦合:是对一个软件结构内不同模块间互连程序的度量。耦合强度取决于模块接口的复杂程度、通过接口的数据等。耦合度越高,模块独立性越弱
内聚:是用来度量一个模块内部各个元素彼此结合的紧密程度。内聚度越高,紧密程度越高
深度:表示软件结构中控制的层数,能粗略地标志一个系统的大小和复杂程度
宽度:是软件结构内同一个层次上的模块总数的最大值
扇出:是一个模块直接控制的模块数目
扇入:表明有多少个上级模块直接调用它。扇入越大则共享该模块的上级模块数目越多。但是,不能违背模块独立原理单纯追求高扇入
独立性
(1)定义
模块独立:开发具有独立功能而且和其他模块之间没有过多的相互作用的模块,就可以做到模块独立。使得每个模块完成一个相对独立的特定子功能,并且和其他模块之间的关系很简单。模块独立的概念是模块化、抽象、信息隐藏和局部化概念的直接结果。其质量标准是耦合和内聚
(2)重要性
具有独立的模块的软件比较容易开发出来
独立的模块比较容易测试和维护
(3)模块耦合及其分类
A:定义
耦合:是对一个软件结构内不同模块间互连程序的度量。耦合强度取决于模块接口的复杂程度、通过接口的数据等。耦合度越高,模块独立性越弱
耦合度低到高:
- 完全独立
- 数据耦合
- 特征耦合
- 控制耦合
- 外部耦合
- 公共耦合
- 内部耦合
内聚:是用来度量一个模块内部各个元素彼此结合的紧密程度。内聚度越高,紧密程度越高
内聚度由低到高为
- 偶然内聚
- 逻辑内聚
- 时间内聚
- 过程内聚
- 通信内聚
- 顺序内聚
- 功能内聚
高内聚,低耦合
启发性规则
启发规则有:
- 改进软件结构提高模块独立性
- 模块规模应该适中
- 深度、宽度、扇入和扇出应适当
- 模块的作用域应该在控制域之内
- 力争降低模块接口的复杂程度
- 设计单入口单出口的模块
- 模块功能应该可以预测但要防止过分局限
八.测试
黑盒测试着眼于程序的外部特征,而不考虑程序的内部结构。测试时、测试者把被测程序看作是一个黑盒,仅以程序的功能为依据,看其是否满足功能要求。
白盒测试着眼于程序的内部结构。测试者对程序的内部逻辑与处理过程了如指掌,并依据程序的逻辑结构,对程序的所有逻辑路径进行测试,确定其实际状态与预期的状态是否一致。
软件测试步骤
(1)单元测试(模块测试)(2)子系统测试(3)系统测试
(4)验收测试(确认测试)(5)平行运行
在测试过程中,由于模块并不是一个独立的程序,因此必须为每个单元测试开发驱动程序和存根程序
九.面向对象方法学
概念
(1)基本原则
面向对象方法学的出发点和基本原则,是尽可能模拟人类习惯的思维方式,使开发软件的方法与过程尽可能接近人类认识世界解决问题的方法与过程,使描述问题的问题空间(问题域)与实现解法的解空间(求解域)在结构上尽可能一致
(2)定义
面向对象方法是一种以数据或信息为主线,把数据和处理相结合的方法,即把对象作为由数据及可以施加在这些数据上的操作所构成的统一体。面向对象的方法可以用下列方程来概括:
(3)要点
对象:面向对象的软件系统是由对象组成的,软件中的任何元素都是对象,复杂的软件对象由比较简单的对象组合而成。用对象分解取代了传统方法的功能分解,对象是从客观世界中的实体抽象而来的,是不固定的
类:把所有对象都划分成各种对象类,每个对象类都定义了一组数据和一组方法。数据用于表示对象的静态属性,是对象的状态信息。类中定义的方法,是允许施加于该类对象上的操作,是该类所有对象共享的,并不需要为每个对象都复制操作的代码
继承性:按子类与父类的关系,把若干个对象类组成一个层次结构的系统。子类自动具有和上层的父类相同的数据和方法,而且低层的特性将屏蔽高层的同名特性,子类成员会对同名父类成员进行屏蔽,这种情况我们称之为隐藏,或者叫做重定义
封装性:对象彼此之间仅能通过传递消息互相联系。对象是进行处理的主体,必须发消息请求它执行它的某个操作,处理它的私有数据,而不能从外界直接对它的私有数据进行操作。一切局部于该对象的私有信息,都被封装在该对象类的定义中,就好像装在一个不透明的黑盒子中一样,在外界是看不见的,更不能直接使用,
面向对象相关概念
面向对象
特点:封装、继承、多态
基本概念
1、面向对象:按人们认识客观世界的系统思维方式,采用基于对象的概念建立模型,模拟客观世界分析、设计、实现软件的办法。
2、对象:即指现实世界中各种各样的实体。
3、类:类是具有相似内部状态和运动规律的实体的合计。
面向对象的软件工程方法的优势
1、符合人类的思维习惯
2、稳定性好
3、可复用性好
4、可维护性好
一:对象(Object)
(1)对象的形象表示
下图形象地描绘了具有3个操作的对象。图9-1形象地描绘了具有3个操作的对象。面向对象方法学中的对象是由描述该对象属性的数据以及可以对这些数据施加的所有操作封装在一起构成的统一体。对象可以作的操作表示它的动态行为
(2)对象的定义按照面向对象程序设计的角度:对象是具有相同状态的一组操作的集合。 在应用领域中有意义的、与所要解决的问题有关系的任何事物都可以作为对象,它既可以是具体的物理实体的抽象,也可以是人为的概念,或者是任何有明确边界和意义的东西
按照结构化角度:对象是封装了数据结构及可以施加在这些数据结构上的操作的封装体,这个封装体有可以唯一地标识它的名字,而且向外界提供一组服务。对象中的数据表示对象的状态,一个对象的状态只能由该对象的操作来改变。每当需要改变对象的状态时,只能由其他对象向该对象发送消息。对象响应消息时,按照消息模式找出与之匹配的方法,并执行该方法
(3)对象的特点
1.以数据为中心
操作围绕对其数据所需要做的处理来设置,不设置与这些数据无关的操作,而且操作的结果往往与当时所处的状态有关
2.对象是主动的
对象进行处理的主体。不能从外部直接加工它的私有数据,而是必须通过它的公有接口向对象发消息,请求它执行它的某个操作,处理它的私有数据
3.实现了数据封装
私有的数据完全被封装在内部,对外是隐藏的、不可见的,对私有数据的访问或处理只能通过公有的操作进行。为了使用对象内部的私有数据,只需知道数据的取值范围和可以对该数据施加的操作。一个对象类型也可以看作是一种抽象数据类型。
4.具有并行性
对象是描述其内部状态的数据及可以对这些数据施加的全部操作的集合。不同对象各自独立地处理自身的数据,彼此通过发消息传递信息完成通信。因此,本质上具有并行工作的属性。
5.模块独立性好
对象是由数据及可以对这些数据施加的操作所组成的统一体,而且对象是以数据为中心的,操作围绕对其数据所需做的处理来设置,没有无关的操作。因此,对象内部各种元素彼此结合得很紧密,内聚性相当强。它与外界的联系比较少,对象之间的耦合比较松
二:类
“类”是对具有相同数据和相同操作的一组相似对象的定义,即类是对具有相同属性和行为的一个或多个对象的描述,包括对怎样创建该类的新对象的说明。类是支持继承的抽象数据类型,而对象就是类的实例
类就是在定义一种类型,而对象是类实例化出来的。类相当于一个模板,对象是根据模板造出来的
三:实例
实例就是由某个特定的类所描述的一个具体的对象。类是对具有相同属性和行为的一组相似的对象的抽象,类在现实世界中并不能真正存在。实际上类是建立对象时使用的“样板”,按照这个样板所建立的一个个具体的对象,就是类的实际例子,通常称为实例
四:消息
消息就是要求某个对象执行在定义它的那个类中所定义的某个操作的规格说明。一个消息由接收消息的对象、消息选择符、零个或多个变元组成。
例如一个类中定义了某个打印函数,它要接受一个字符串,所以对象在执行时就会调用它,接着传入参数即可,这里的参数就是规格说明
五:方法
方法就是对象所能执行的操作,也就是类中所定义的服务。方法描述了对象执行操作的算法,响应消息的方法
例如C++中类的成员函数就是方法
六:属性
属性就是类中所定义的数据,它是对客观世界实体所具有的性质的抽象。类的每个实例都有自己特有的属性值
七:封装
(1)定义
封装是把数据和实现操作的代码集中起来放在对象内部。封装也就是信息隐藏,通过封装对外界隐藏了对象的实现细节
(2)特点有一个清晰的边界
有确定的接口
受保护的内部实现
八:继承
(1)定义
广义地说,继承是指能够直接获得已有的性质和特征,而不必重复定义它们。在面向对象的软件技术中,继承是子类自动地共享父类中定义的数据和方法的机制
在这里插入图片描述
(2)特点继承具有传递性
子类将会屏蔽父类的同名性质(3)继承的优点(了解)
使得相似的对象可以共享程序代码和数据结构,大大减少程序中的冗余信息
便于软件维护和开发
用户在开发新系统时不需要从零开始,可以继承原有相似功能或者从类库中选取需要的类,然后再派生新类
九:多态性
(1)多态
多态性是指子类对象可以像父类对象那样使用,同样的消息既可以发送给父类对象也可以发送给子类对象。即在类等级的不同层次中可以共享一个方法的名字, 不同层次中的每个类各自按自己的需要来实现这个行为
比如经典的买票行为,学生和普通人都属于人,但是学生买票可以半价,而普通人则只能全票,但是他们买票的这个接口实现的原理肯定是一样的,只是策略不同
(2)优点
增加了面向对象软件系统的灵活性,进一步减少信息冗余
提高了可重用性和可扩充性
十:重载
函数重载:在同一作用域,若干个参数特征不同的函数可以使用相同的函数名, C++可以有同名函数的原因就是支持函数重载
运算符重载:同一个运算符可以施加于不同类型的操作数上面
用例图
拓展:向一个用例添加另一个用例,例如售货为一个用例,买瓶装可乐是售货的一个拓展,买散装可乐也是一个拓展
使用:多个用例使用同一个用例
十.面向对象分析
数据结构(对象模型)、执行操作(动态模型)、数据值变化(功能模型)
建立对象模型
(1)定义
对象模型表示静态的、结构化的系统的数据性质。它是对模拟客观世界实体的对象以及对象彼此间的关系的映射,描述了系统的静态结构。对象模型为建立动态模型和功能模型,提供了实质性的框架。
使用UML(统一建模语言)提供的类图来建立对象模型
典型的建模步骤
- 确定对象类和关联(对于大型复杂问题还要进一步划分出若干个主题);
- 给类和关联增添属性,以进一步描述它们;
- 使用适当的继承关系进一步合并和组织类
建立动态模型
概念
A:适用性对于仅存储静态数据的系统来说,动态模型并没有什么意义
在开发交互式系统时,动态模型却起着很重要的作用
收集输入信息是系统的主要工作时,则在开发时建立正确的动态模型是至关重要的
B:步骤
编写典型交互行为的脚本
从脚本中提取出事件,确定触发每个事件的动作对象以及接受事件的目标对象
排列事件发生的次序,确定每个对象的状态及状态间的转换关系,用状态图描绘
比较各个对象的状态图,确保事件之间的匹配编写脚本:分析用户对系统交互行为的要求的过程
设想用户界面
画事件跟踪图
画状态图
建立功能模型
功能模型表明了系统中数据之间的依赖关系,以及有关的数据处理功能,它由一组数据流图组成。在建立了对象模型和动态模型之后再建立功能模型
画出基本系统模型图
画出功能级数据流图
描述处理框功能
十一.面向对象设计
启发规则
(1)设计结果应该清晰易懂
(2)一般一特殊结构的深度适当
(3)设计简单的类
(4)使用简单的协议
(5)使用简单的服务(6)把设计变动减至最小
软件重用
重用也叫再用或复用,是指同一事物不作修改或稍加改动就多次重复使用。
软件重用可分为以下3个层次:
- 知识重用;
- 方法和标准的重用;
- 软件成分的重用
十二.面向对象实现
程序设计风格(编码风格)
(1)概念
A:良好的程序设计风格的重要性能明显减少维护或扩充的开销
有助于在新项目中重用已有的程序代码B:良好的面向对象程序设计风格内容
传统的程序设计风格准则
为适应面向对象方法所特有的概念而必须遵循的一些新准则
(2)提高可重用性
A:代码重用内部重用:即本项目内的代码重用,主要是找出设计中相同或相似的部分,然后利用继承机制共享它们
外部重用:即新项目重用旧项目的代码,需要有长远眼光,反复考虑,精心设计B:主要准则
①:提高方法的内聚
②:减小方法的规模
③:保持方法的一致性
④:把策略与实现分开策略方法:策略方法应该检查系统运行状态,并处理出错情况,它们并不直接完成计算或实现复杂的算法。其紧密依赖于具体应用
实现方法:实现方法仅仅针对具体数据完成特定处理,用于实现复杂的算法。在执行过程中发现错误,它们只返回执行状态而不对错误采取行动。其相对独立于具体应用⑤:全面覆盖
⑥:尽量不使用全局信息
⑦:利用继承机制调用子过程:把公共的代码分离出来,构成一个被其他方法调用的公用方法。可以在基类中定义这个公用方法,供派生类中的方法调用
分解因子:提高相似类代码可重用性的一个有效途径,是从不同类的相似方法中分解出不同的代码,把余下的代码作为公用方法中的公共代码,把分解出的因子作为名字相同算法不同的方法,放在不同类中定义,并被这个公用方法调用
使用委托:继承关系的存在意味着子类“即是”父类,因此,父类的所有方法和属性都应该适用于子类,仅当确实存在一般一特殊关系时,使用继承才是恰当的,当逻辑上不存在一-般一特殊关系时,为重用已有的代码,可以利用委托机制
把代码封装在类中:重用通过其他方法编写的、解决同一类应用问题的程序代码的一个比较安全的途径是把被重用的代码封装在类中
(3)提高可扩充性
主要准则有:
封装实现策略:应该把类的实现策略封装起来,对外只提供公有的接口,否则将降低今后修改数据结构或算法的自由度
不要用一个方法遍历多条关联链:一个方法应该只包含对象模型中的有限内容。违反这条准则将导致方法过分复杂,既不易理解,也不易修改扩充
避免使用多分支语句:可以利用DO_CASE语句测试对象的内部状态,而不要用来根据对象类型选择应有的行为,否则在增添新类时将不得不修改原有的代码
精心确定公有方法
(4)提高健壮性
主要准则有:
预防用户的错误操作
检查参数的合法性
不要预先确定限制条件
先测试后优化
测试策略
(1)经典的测试策略
测试软件的经典策略是,从“小型测试”开始,逐步过渡到“大型测试”。用软件测试的专业术语描述,可以分为以下三步:
单元测试
集成测试
确认测试,系统测试
(2)面向对象测试策略
A:面向对象的单元测试
最小的可测试单元是封装起来的类和对象。测试面向对象软件时,不能再孤立地测试单个操作,而应该把操作作为类的一部分来测试。
B:面向对象的集成测试
①:策略
基于线程的测试:把响应系统的一个输入或一个事件所需要的那些类集成起来。分别集成并测试每个线程,同时应用回归测试以保证没有产生副作用
基于使用的测试:不使用服务器类的独立类,把独立类都测试完之后,再测试使用独立类的下一个层次的类(称为依赖类)。对依赖类的测试一层一层次地测试,直至把整个软件系统构造完为止
②:集群测试
集群测试是面向对象软件集成测试的一个步骤。在这个测试步骤中,用精心设计的测试用例检查一群相互协作的类,这些测试用例力图发现协作错误
C:面向对象的确认测试
在确认测试或系统测试层次,不再考虑类之间相互连接的细节。面向对象软件的确认测试也集中检查用户可见的动作和用户可识别的输出。为了导出确认测试用例,测试人员应该认真研究动态模型和描述系统行为的脚本,以确定最可能发现用户交互需求错误的情景
设计测试用例
(1)测试类的方法
A:随机测试
B:划分测试
①:优点采用划分测试方法可以减少测试类时所需要的测试用例的数量
②:流程把输入和输出分类
设计测试用例以测试划分出的每个类别③:方法
基于状态的划分:根据类操作改变类状态的能力来划分类操作
基于属性的划分:根据类操作使用的属性来划分类操作
基于功能的划分:根据类操作所完成的功能来划分类操作C:基于故障的测试
(2)集成测试方法
A:多类测试
①:随机测试对每个客户类,使用类操作符列表来生成一系列随机测试序列
对所生成的每个消息,确定协作类和在服务器对象中的对应操作符
对服务器对象中的每个操作符,确定传递的消息
对每个消息,确定下一层被调用的操作符,并把这些操作符结合进测试序列中②:划分测试
应该扩充测试序列以包括那些通过发送给协作类的消息而被调用的操作
根据与特定类的接口来划分类操作B:从动态模型导出测试用例
类的状态图可以帮助人们导出测试该类的动态行为的测试用例。通过导出大量的测试用例,保证该类的所有行为都被适当地测试了。在类的行为导致与一个或多个类协作的情况下,应该使用多个状态图去跟踪系统的行为