软件工程导论
1. 软件工程的7条基本原理:
用分阶段的生命周期计划严格管理;坚持进行阶段评审;实行严格的产品控制;采用现代程序设计技术;结果应能清楚的审查;开发小组的人应该少而精;承认不断改进软件工程实践的必要性。
2. 软件工程方法学包括:
方法,工具和过程。传统方法学也称为生命周期方法学或者结构化规范。它采用结构化技术(结构化分析,结构化设计和结构化实现)来完成软件开发的各项任务,并使用适当的软件工程工具来支持结构化技术的应用。
3. 软件生命周期:
三个周期,八个阶段。三个周期:软件定义,软件开发,和运行维护。八个阶段:1问题定义2可行性研究
3需求分析 4总体设计 5详细设计 6编码和单元测试7综合测试 8软件维护
4. 软件过程:
1瀑布模型 2快速原型模型 3增量模型 4螺旋模型5喷泉模型 6Rational统一过程 7敏捷过程与极限编程
8微软过程
5. 数据流图:
数据流图是一种图形化的技术,它描绘信息流和数据从输入移动到输出的过程中所经受的变换。
数据流图有4种成分:源点或者终点,处理,数据存储和数据流。
数据流图的基本目的是利用它作为交流信息的工具,作为分析和设计的工具。
6. 数据字典:
数据字典是关于数据的信息的集合,也就是对数据流图中所包含的所有元素的定义的集合。包含:1数据流,2,数据流分量(即数据元素),3,数据存储,4,处理。
7. 如何定义数据的方法?
答:数据字典中的定义就是自顶向下的分解。当分解到不需要进一步定义,每个和工程有关的人也都清楚其含义的元素时,分解也就相应的完成。
由数据元素组成数据的方式只有以下3中基本类型:
1/顺序 即以确定次序连接两个或者多个分量。
2/选择 即从两个或者多个可能的元素中选取一个。
3/重复 即把指定的分量重复零次或者多次。
4/可选 即一个分量是可有可无的(重复零次或者一次)。
8. 数据字典的用途:
1/ 作为分析阶段的工具。
2/ 数据字典中包含的每个数据元素的控制信息是很有价值的。
3/ 数据字典是开发数据库的第一步,是很有价值的一步。
9. 成本估计:
代码行技术 任务分解技术 自动估计成本技术
成本效益分析方法:1,货币的时间价值 2投资回收期 3纯收入 4投资回收率
10. 分析方法都应该遵守以下准则:
1/ 必须理解并且描述问题的信息域,根据这条准则建立数据模型。
2/ 必须定义软件应该完成的功能,这条准则要求建议功能模型。
3/ 必须描述作为外部事件结果的软件行为,这条准则要求建立行为模型。
4/ 必须对描述信息,功能和行为的模型进行分解,用层次的方式细节。
11. 需求分析的任务有什么?
功能需求 性能需求 可靠性和可用性分析需求 出错处理需求 接口需求 约束 逆向需求 将来可能提出的要求
12. 与用户沟通获取需求的方法:
1,访谈 2,面向数据流自顶向下求精 3,简易的应用规格说明技术 4,快速建立软件原则
13. 图形工具:
层次方框图 Warnier图 IPO图
1 层次方框图
层次方框图用树形结构的一系列多层次的矩形框描绘数据的层次结构。
例如,描绘一家计算机公司全部产品的数据结构可以用下图层次方框图表示。
这家公司的产品由硬件、软件和服务3类产品组成,软件产品又分为系统软件和应用软件,系统软件又进一步分为操作系统、编译程序和软件工具等。
2 warnier图
和层次方框图类似,Warnier图也用树形结构描绘信息,但是这种图形工具比层次方框图提供了更丰富的描绘手段。
用Warnier图可以表明信息的逻辑组织,也就是说,它可以指出一类信息或一个信息元素是重复出现的,也可以表示特定信息在某一类信息中是有条件地出现的。
3 IPO图
IPO图是输入、处理、输出图的简称,它是由美国IBM公司发展完善起来的一种图形工具,能够方便地描绘输入数据、对数据的处理和输出数据之间的关系。
14. 内聚和耦合:
耦合:是对一个软件结构内各个模块之间相互依赖程度的度量;耦合的强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。
内聚:则标志一个模块内各个元素彼此结合的紧密程度;内聚从功能角度衡量模块内的联系,好的内聚模块应当恰好做一件事。
需求的原则是:强内聚,弱耦合。然而在实际需求过程中,往往会因为技术驱动,导致需求间耦合很紧,不利于后期有效地迭代开发。有效的解决办法是按流程、和业务梳理需求。
1.首先,我们来明确什么是模块
模块是一系列语句组成的,由标识符组成的边界元素来界定的。比如面向对象语言中的一个类、一个方法;也如面向过程中的函数。
2.内聚
所谓的内聚是指模块内的交互程度,内聚又分为一下几种
偶然性内聚:组件的部件是不相关的,只是简单地绑定成单个组件。
不足:程序的可读性和复用性差
逻辑性内聚:把相似的功能(类如输入,错误处理)放在一块,通过传递一个参数来决定是哪一个功能来执行。
不足:接口可读性差,代码复用性低
时间性内聚:所有的语句在同一时刻被激活,就像电脑关机的时候,其他所有的程序都要被关闭。
不足:模块内的关联不高,而与模块外的关联却很高,所以在维护的时候工作量会 比较大。
过程性内聚:简单地把一系列过程关联在一起
不足:代码的复用性比较差
通信性内聚:操作相同的输入数据或者输出相同的输出数据,可能产生多种功能。
不足:代码的复用性不高
顺序内聚:从一个部分的输出作为另一部分的输入。可能包含几个功能或部分不同的功能。
不足:代码的复用性不高
信息聚合:执行多个功能,每个函数都有自己的入口点,每个函数都有独立的代码,所有的功能都在相同的数据结构上执行。不同于逻辑衔接,因为功能没有交织在一起。
功能内聚:每一部分都需要执行一个单一的功能。例如,计算平方根或排序数组。通常在其他情况下可重复使用。维修容易。
以上几种内聚程度由低到高
耦合:耦合是指模块之间的交互程度
内容耦合:如果一个模块直接操作操作另外一个模块中的内容,比如下面的代码:
public class Product {
public float unitPrice;
……
}
public class Order {
private Product myProduct=new Product();
myProduct.unitPrice = -100;
}
}
公共耦合:就像一个类中的全局变量类中的模块都直接操作这个全局变量
控制耦合:通过控制标志(作为参数或变量),一个模块控制另一个模块的处理步骤的顺序。
印记耦合:如果一组模块通过参数表传递记录信息,就是印记耦合。事实上,这组模块共享了这个记录,它是某一数据结构的子结构,而不是简单变量。这要求这些模块都必须清楚该记录的结构,并按结构要求对此记录进行操作。在设计中应尽量避免这种耦合,它使在数据结构上的操作复杂化了
数据耦合:如果一个模块访问另一个模块时,彼此之间是通过数据参数(不是控制参数、公共数据结构或外部变量)来交换输入、输出信息的,则称这种耦合为数据耦合。由于限制了只通过参数表传递数据,按数据耦合开发的程序界面简单、安全可靠。因此,数据耦合是松散的耦合,模块之间的独立性比较强。在软件程序结构中至少必须有这类耦合。
以上所有的耦合度有高到低,越低的耦合越好。
15. 启发规则有哪些?
1/改进软件结构提高模块儿独立性。2/模块规模应该适中 3/深度,宽度,扇入和扇出都应该适当 4/模块儿的作用域应该在控制域内。 5/力争降低模块儿接口的复杂度 6/设计单入口和单出口的模块儿。 7/模块儿功能应该预测。
16. 描绘软件结构的图形工具有哪些?
层次图,HIPO图 结构图
层次图和HIPO图
层次图用来描述软件的层次结构。虽然层次图的形式和描绘数据结构的层次方框图相同,但是表现的内容却完全不同。层次图中的一个矩形框代表一个模块,方框间的连线表示调用关系而不像层次方框图那样表示组成关系。下图是层次图的一个例子,最顶层的方框代表正文加工系统的主要模块,它调用下层模块完成正文加工的全部功能;第二层的每个模块控制完成正文加工的一个主要功能,例如“编辑”模块通过调用它的下属模块可以完成6钟编辑功能中的任何一种。
层次图很适合在自顶向下设计软件的过程中使用。
HIPO图是美国IBM公司发明的“层次图加输入/处理/输出图”的英文缩写。为了能使HIPO图具有可追踪性,在H图(层次图)里除了最顶层的方框之外,每个方框都加了编号。如下图:
和H图中每个方框相对应,应该有一张IPO图描绘这个方框代表的模块的处理处理过程。下面再详细介绍IPO图。但是有一点应该指出,那就是HIPO图中的每张IPO图内都应该明显地标出它所描述的模块在H图中的编号,以便追踪了解这个模块在软件结构中的位置。
IPO图是输入、处理、输出图的简称,它是由美国IBM公司发展完善起来的一种图形工具,能够方便地描绘输入数据,对数据处理和输出数据之间的关系。
IPO图使用的基本符号既少又简单,因此很容易学会使用这种图形工具。它的基本形式是在左边的框中列出有关的输入数据,在中间的方框内列出主要的处理,在右边的框内列出产生的输出数据。处理框内列出处理的次序暗示了执行的顺序,但是用这些基本符号还不足以精确描述执行处理的详细情况。在IPO图中还用类似向量符号的粗大箭头清楚的指出数据通信的情况。下图是一个主文件更新的例子,通过这个例子不难了解IPO图的用法。
小编建议使用一种改进的IPO图(也成为IPO表),使用图中包含某些附加的信息,在软件设计过程中将比原始的IPO图更有用。下图是改进的IPO图中包含的附加信息主要有系统名称、图的作者、完成的日期、本图描述的模块的名字、模块在层次图中的编号、调用本模块的模块清单、本模块调用的模块的清单、注释以及本模块使用的局部数据元素等。在需求分析阶段可以使用IPO图简略地描述系统的主要算法(即数据流图中各个处理的基本算法)。
当然,在需求分析阶段,IPO图中的许多附加信息暂时还不具备,但是在软件设计阶段可以进一步不充修正这些图,作为设计阶段的文档。这正是在需求分析阶段用IPO图作为描述算法的工具的重要优点。
17. 面向数据流的设计方法?
交换流:信息沿输入通路进入系统,同时由外部形势变换为内部形式,进入系统的信息通过变换中心,经加工处理以后再沿输出通路变换成外部形式离开软件系统。
事务流:沿传入路径进入系统,由外部形式变换位内部形式后到达事务中心,事务中心根据数据项计值结果从若干动作路径中选定一条执行。有这样形状的成为事务流。
18. 变换分析
变换分析是一系列设计步骤的总称,经过这些步骤把具有交换流特点的数据流图按预先确定的模式映射成软件结构。
1.变换流
信息沿输入通路进入系统,由外部形式变换成内部形式,进入系统的信息通过变换中心,经加工处理以
后再沿输出通路变换成外部形式离开软件系统。当数据流图具有这些特征时,这种信息流就叫作变换流。
2.事务流
数据沿输入通路到达一个处理T,这个处理根据输入数据的类型在若干个动作序列中选出一个来执行。这
类数据流应该划为一类特殊的数据流,称为事务流。图中的处理T称为事务中心,它完成下述任务。
(1)接收输入数据(输入数据又称为事务)。
(2) 分析每个事务以确定它的类型。
(3) 根据事务类型选取一条活动通路.
3.变换分析
第1步复查基本系统模型
第2步复查并精化数据流图。
第3步确定数据流图具有变换特性还是事务特性。
第4步确定输入流和输出流的边界,从而孤立出变换中心。
第5步完成“第一级分解
软件结构代表对控制的自顶向下的分配,所谓分解就是分配控制的过程。对于变换流的情况,数据流图被映射成一个特殊的软件结构,这个结构控制输入、变换和输出等信息处理过程。位于软件结构最顶层的控制模块Cm协调下述从属的控制功能。输入信息处理控制模块Ca,协调对所有输入数据的接收。变换中心控制模块Ct,管理对内部形式的数据的所有操作。输出信息处理控制模块Ce,协调输出信息的产生过程。
第6步完成“第二级分解”
第二级分解就是把数据流图中的每个处理映射成软件结构中一个适当的模块。
第7步使用设计度量和启发式规则对第一次分割得到的软件结构进一步精化。
19. 事务分析:
事务分析由数据流图到软件结构的映射方法分为一个接收分支,一个发送分支。
20. 设计优化:
软件设计人员应该致力于开发能够满足所有功能和性能要求,而且按照设计原则和启发式设计规则衡量是指的接收的软件。应该在设计的早期阶段尽量对软件结构进行精化。而且可以导出不同的软件结构,然后对他们进行评价和比较,力求得到“最好”的结果。
21. 顺序 选择 循环
22. 过程设计的工具有哪些?
程序流程图 盒图 PAD图 判定表 判定树 过程设计语言
23. Jackson图
顺序结构 选择结构 重复结构
Jackson设计方法
概述
Jackson方法是面向数据结构的设计方法。
JSP方法定义了一组以数据结构为指导的映射过程,它根据输入、输出的数据结构,按一定的规则映射成软件的过程描述,即程序结构,而不是软件的体系结构,因此该方法适用于详细设计阶段。
Jackson结构图
由于Jackson方法面向数据结构设计,所以提供了自己的工具——Jackson结构图。Jackson指出,无论数据结构还是程序结构,都限于三种基本结构及它们的组合,因此,他给出了三种基本结构的表示。
1. 顺序结构
2. 选择结构
3. 重复结构
JSP设计步骤
JSP方法一般通过以下五个步骤来完成设计:
(1)分析并确定输入数据和输出数据的逻辑结构,并用Jackson结构图来表示这些数据结构。
(2)找出输入数据结构和输出数据结构中有对应关系的数据单元。
(3)按一定的规则由输入、输出的数据结构导出程序结构。
(4)列出基本操作与条件,并把它们分配到程序结构图的适当位置。
(5)用伪码写出程序。
JACKSON分析方法
面向数据流的分析方法
JACKSON方法是一套完成的分析和设计方法。Jackson认为有三种形式的数据结构。、顺序、选择和重复。三种数据结构可以进行任意嵌套,组合。形成复杂的结构体系。JACKSON方法的从目标系统的输入、输出数据结构入手,导出程序框架结构,再补充其它细节,就可得到完整的描述程序结构的JACKSON图。
我在实际中,我没有完整的使用过JACKSON方法(实际上,我也没有系统的学习过这种方法)。我只在分析阶段,经常使用JACKSON图描述复杂的要处理的数据的逻辑结构。我把这种只把JACKSON方法用来做分析的方法,称为JACKSON方法。
JACKSON方法的主要思路,就是:通过对要处理的复杂数据,绘制JACKSON图进行分析,了解需求。
另外,除了使用JACKSON图来完成分析,我还使用过JACKSON图,来描述过复杂配置文件的文件结构。因为JACKSON图关注与数据的逻辑结构,而不比关心数据的具体存在形式。用来设计配置文件的格式,挺合适的。
24. McCabe方法计算环形复杂度
环形复杂度定量度量程序的逻辑复杂度。描绘程序控制流的流图之后,可以用下述3种方法中的任何一种来计算环形复杂度。
(1)流图中的区域数等于环形复杂度。
(2)流图G的环形复杂度V(G)=E-N+2,其中,E是流图中边的条数,N是结点数。
(3)流图G的环形复杂度V(G)=P+1,其中,P是流图中判定结点的数目。
25. 软件测试的定义目标:
[1]. 测试是为了发现程序中的错误而执行程序的过程。
[2]. 好的测试方案是极有可能发现迄今为止尚未发现的错误的测试方案。
[3]. 成功的测试是发现了至今为止尚未发现的错误的测试。
26. 软件测试准则:
[1]. 所有的测试都应该追溯到客户需求。
[2]. 应该在测试之前就应该制定出测试计划。
[3]. 把Pareto原理应用到软件测试中。错误的80%是有程序中的20%的模块造成的。
[4]. 应该从“小规模”测试开始,并逐步进行“大规模”
测试。
[5]. 请举测试是不可能的。
[6]. 为了达到最佳的测试效果,应该由独立的第三方
从事测试工作。
27. 测试方法:
静态测试 和 动态测试 动态测试又分为黑盒测试和白盒
测试。黑盒测试是功能测试,不考虑内部结构。白盒测试
是结构测试,需要考虑内部的逻辑结构。
28. 测试步骤:
模块儿测试(单元测试) 子系统测试 系统测试验收测试 平行运行
29. 单元测试:
单元测试期间着重从下面五个方面进行测试。1.接口模块 2. 局部数据结构 3.重要的执行通路 4.出错处理通路
5 边界条件
30. 集成测试:
集成测试是测试和组装软件的系统化技术。集成测试(也叫组装测试,联合测试)是单元测试的逻辑扩展。它最简单的形式是:把两个已经测试过的单元组合成一个组件,测试它们之间的接口。从这一层意义上讲,组件是指多个单元的集成聚合。集成测试有非渐进式测试和渐进式测试。普遍采用渐进式测试。
31. 回归测试:
回归测试是指重新执行已经做过的测试的某个子集,以保证上述这些变化没有带来非预期的副作用。
32. 等价划分方法:
1.定义
是把所有可能的输入数据,即程序的输入域划分成若干部分(子集),然后从每一个子集中选取少数具有代表性的数据作为测试用例。该方法是一种重要的,常用的黑盒测试用例设计方法。
2.划分等价类:
等价类是指某个输入域的子集合。在该子集合中,各个输入数据对于揭露程序中的错误都是等效的,并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试,因此,可以把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件就可以用少量代表性的测试数据取得较好的测试结果。等价类划分可有两种不同的情况:有效等价类和无效等价类。
1)有效等价类
是指对于程序的规格说明来说是合理的、有意义的输入数据构成的集合。利用有效等价类可检验程序是否实现了规格说明中所规定的功能和性能。
2)无效等价类
与有效等价类的定义恰巧相反。无效等价类指对程序的规格说明是不合理的或无意义的输入数据所构成的集合。对于具体的问题,无效等价类至少应有一个,也可能有多个。
设计测试用例时,要同时考虑这两种等价类。因为软件不仅要能接收合理的数据,也要能经受意外的考验,这样的测试才能确保软件具有更高的可靠性。
3.划分等价类的标准:
1)完备测试、避免冗余;
2)划分等价类重要的是:集合的划分,划分为互不相交的一组子集,而子集的并是整个集合;
3)并是整个集合:完备性;
4)子集互不相交:保证一种形式的无冗余性;
5)同一类中标识(选择)一个测试用例,同一等价类中,往往处理相同,相同处理映射到"相同的执行路径"。
4.划分等价类的方法
1)在输入条件规定了取值范围或值的个数的情况下,则可以确立一个有效等价类和两个无效等价类。如:输入值是学生成绩,范围是0~100;
2)在输入条件规定了输入值的集合或者规定了"必须如何"的条件的情况下,可确立一个有效等价类和一个无效等价类;
3)在输入条件是一个布尔量的情况下,可确定一个有效等价类和一个无效等价类。
4)在规定了输入数据的一组值(假定n个),并且程序要对每一个输入值分别处理的情况下,可确立n个有效等价类和一个无效等价类。
例:输入条件说明学历可为:专科、本科、硕士、博士四种之一,则分别取这四种这四个值作为四个有效等价类,另外把四种学历之外的任何学历作为无效等价类。
5)在规定了输入数据必须遵守的规则的情况下,可确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则);
6)在确知已划分的等价类中各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步的划分为更小的等价类。
5.设计测试用例
在确立了等价类后,可建立等价类表,列出所有划分出的等价类输入条件:有效等价类、无效等价类,然后从划分出的等价类中按以下三个原则设计测试用例:
1)为每一个等价类规定一个唯一的编号;
2)设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖地有效等价类,重复这一步,直到所有的有效等价类都被覆盖为止;
3)设计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类,重复这一步,直到所有的无效等价类都被覆盖为止。
33. 决定软件可维护性的因素:
可理解性 可测试性 可修改性 可移植性可重用性
34. 面向对象的四个要点:
(1)面向对象的软件系统是由对象组成的,软件中的任何元素都是对象,复杂的软件对象由比较简单的对象组合而成。
(2)把所有对象都划分成各种对象类(简称为类,class),每个对象类都定义了一组数据和一组方法。数据用于表示对象的静态属性,是对象的状态信息。
(3)按照子类(或称为派生类)与父类(或称为基类)的关系,把若干个对象类组成一个层次结构的系统(也称为类等级)。
(4)对象彼此之间仅能通过传递消息互相联系。
UML中类与类,已经类与接口,接口与接口的关系有:泛化(generalization),关联(association),依赖(dependency),实现(realization)这几种。
泛化(generalization)关系时指一个类(子类、子接口)继承另外一个类(称为父类、父接口)的功能,并可以增加它自己新功能的能力,继承是类与类或者接口与接口最常见的关系,在Java中通过关键字extends来表示。
实现(realization)是指一个class实现interface接口(一个或者多个),表示类具备了某种能力,实现是类与接口中最常见的关系,在Java中通过implements关键字来表示。
依赖(dependency)关系也是表示类与类之间的连接,表示一个类依赖于另外一个类的定义,依赖关系时是单向的。简单理解就是类A使用到了类B,这种依赖具有偶然性、临时性,是非常弱的关系。但是类B的变化会影响到类A。举个例子,如某人要过河,则人与船的关系就是依赖,人过河之后,与船的关系就解除了,因此是一种弱的连接。在代码层面,为类B作为参数被类A在某个方法中使用。
在java中,依赖表现为:局部变量,方法中的参数和对静态方法的调用。
关联(association)关系表示类与类之间的连接,它使得一个类知道另外一个类的属性和方法。
关联可以使用单箭头表示单向关联,使用双箭头或者不适用箭头表示双向关联,不建议使用双向关联,关联有两个端点,每个端点可以有一个基数,表示这个关联的类可以有几个实例。
0..1 表示可以有0个或者1个实例
0..* 表示对实例的数目没有限制
1 表示只能有一个实例
1..* 表示至少有一个实例
关联关系体现的是两个类,或者类与接口之间的强依赖关系,这种关系很强烈,比依赖更强,不是偶然性的,也不是临时性的,而是一种长期性,相对平等的关系,表现在代码层面,为被关联的类B以类属性的形式出现在类A中,也可能是关联类A引用了被关联类B的全局变量。
在Java中,关联关系是使用实例变量来实现的
聚合(aggregation)是关联关系的特例,是强的关联关系,聚合是整个与个体的关系,即has-a关系,此时整体和部分是可以分离的,他们具有各自的生命周期,部分可以属于多个对象,也可以被多个对象共享;比如计算机和CPU,公司与员工的关系;在代码层面聚合与关联是一致的,只能从语义上来区分。
聚合关系也是使用实例变量来实现的,在java语法上区分不出关联和聚合,关联关系中类出于一个层次,而聚合则明显的在两个不同的层次。
组合(compostion)也是关联关系的一种特例,体现的是一种contain-a关系,比聚合更强,是一种强聚合关系。它同样体现整体与部分的关系,但此时整体与部分是不可分的,整体生命周期的结束也意味着部分生命周期的结束,反之亦然。如大脑和人类。
体现在代码层面与关联时一致的,只能从语义来区分。
组合与聚合几乎完全相同,唯一区别就是对于组合,“部分”不同脱离“整体”单独存在,其生命周期应该是一致的。
总结:
主要是关联关系的细化需要注意强弱,由若到强分别是依赖 < 关联 < 聚合 < 组合