以下是我今天阅读《软件工程理论与应用》(http://www.amazon.cn/gp/product/B008269QRW/ref=fs_rd_1)时在kindle上做的笔记。软件项目管理的那章我基本上没有记,因为觉得目前去背这个有点地命海心了,等我真的有人可管理了再去看。
软件工程理论与应用 (21世纪全国高校应用人才培养信息技术类规划教材)
通过瀑布模型框架结构可以看到一般软件系统的开发步骤分为3个阶段:计划阶段、开发阶段、维护阶段。 ● 在计划阶段主要完成对系统可行性的论证,描述系统的定义、范围与系统实现的意义; ● 开发阶段分为4个步骤:系统需求分析、系统设计、系统实现、测试; ● 维护阶段完成系统在运行过程中所做的修改。
瀑布模型从软件制作时间上按工序把项目分为有序的步骤,实现了流水线的生产方式,便于分工协作,
瀑布模型拥有简单的管理模型以及设计和实现分离的特征,系统鲁棒性(Robust)强、容易修改,适合于需求明确的大型系统开发和嵌入式系统的开发。
原型模型(Prototype Model)方式是开发人员根据用户提出的需求快速开发出的一种样本,它向用户展示了待开发软件系统的全部或部分功能和性能,通过原型系统与用户沟通,获得进一步的修改、完善和确认软件系统的需求,并达成一致的理解。
抛弃式原型。
进化式原型。
原型开发模型有内在的特点,着重突出一个“快”字,
增量模型强调每一个增量均发布一个可操作的系统部分,给用户提供了服务功能,也给用户提供了评价的平台。
(1)客户可以很快使用系统,而无须等到整个系统完成之后。 (2)早期的增量可以作为系统原型,用户通过运行早期的版本,评价以后的增量。 (3)项目总体失败的可能性较小,虽然可能某一增量存在问题,但其他一些增量已经交付给用户使用了。
增量模型开发也存在一些问题。如何划分增量、增量大小的确定是实际系统中难以确定的。
它不是将软件过程分为阶段和阶段间的反复来表示,而是采用螺旋旋转方式,每一回路表示软件过程的一个阶段,也即是对应于瀑布模型的相应阶段,
(1)目标制定。确定软件项目的范围、系统实现的目标,选择相应的方案,获取系统的约束条件。 (2)风险分析。每一项目对预选的方案进行风险识别与分析,并采取规避风险的措施。 (3)项目实施。风险分析之后进行系统开发模型的确定,实施软件开发。 (4)评估与规划。
形式化开发模型(Transformational Model)是结合瀑布模型的开发活动并运用数学转换的方式形成的一种开发方法,使得软件工程师能够通过采用严格的、数学的表示方法对软件的开发活动进行数学的描述,
特别适用于安全和保密性要求较高的系统开发。但是,对于一般的应用领域还没有被广泛地应用。
RUP(Rational Unified Process,统一的开发过程)是一个面向对象且基于网络的程序开发方法论。根
由于软件开发模式多种多样,因此复用的方式也不尽相同,其中基于构件的复用是目前最有效的,也是学术界和企业界公认的主流。
软件复用包括三个方面:
XP是一种近螺旋式的开发方法,它将复杂的开发过程分解为一个个相对比较简单的小周期;通过积极的交流、反馈以及其他一系列的方法,开发人员和客户可以非常清楚开发进度、变化、待解决的问题和潜在的困难等,并根据实际情况及时地调整开发过程。 XP方法是建立在开发和交付非常小的功能增量方式上的,客户参与开发过程,经常性地进行代码改进和非自我程序设计。
对于大量的Web开发具有用户需求不明确,用户对预期的开发结果难以准确描述的特点,采用Web快速原型模型,
计算机辅助软件工程(Computer-Aided Software Engineering, CASE)是用来支持软件过程活动的软件,
工具类。用以支持实现过程的独立工具,如编译器、编辑器、文件比较器等。
工作平台。用以支持开发过程,如支持需求、设计描述等活动的集成度不同的一组集成工具。
环境。用以支持整个软件生存周期过程的所有活动,以一定方式集成的几个工作平台。
项目相关人员涉及对项目有利益关系的人员,
一般来说,需求是对系统应提供的服务和所受到的约束的描述。
用户需求表达了高层的概要需求,系统需求表达对系统应该提供哪些服务的详细描述。
在系统需求说明中,又包括两类需求,称为功能性需求和非功能性需求。
通俗地说,需求分析的任务就是准确地定义未来系统的目标,确定为了满足用户的需求系统必须做什么,用规范的形式准确地表达用户的需求。
具体而言,需求分析主要有两个任务。 第一是通过对问题及其环境的理解、分析和综合,建立分析模型。
第二是在完全弄清用户对软件系统的确切要求的基础上,用“软件需求规格说明书”(Software Requirement Specification, SRS,以下简称需求说明书)把用户的需求表达出来。
(1)扩展关系:若一个用例中加入一些新的动作后构成一个新的用例。 (2)使用关系:当一个用例使用另一个用例时,这两个用例构成使用关系。 (3)组合关系:用例之间存在类似的行为,或相互之间存在必要
(1)扩展关系:若一个用例中加入一些新的动作后构成一个新的用例。 (2)使用关系:当一个用例使用另一个用例时,这两个用例构成使用关系。 (3)组合关系:用例之间存在类似的行为,或相互之间存在必要的关系,可以将相关的用例以封装方式加以组合。
在需求分析阶段,数据流(也称信息流)是系统分析的基础。所谓数据流,形象地说就是系统中“流动的数据结构”。
作为对数据流图的补充,数据字典(Data Dictionary, DD)能够准确地定义数据流图中各组成成分的具体含义。
结构化分析是一个简单实用、使用很广的方法。它适用于分析大型的数据处理系统,特别是企事业管理方面的系统。
E-R(Entity-Relation Diagram,实体-关系图),
DFD,其主要作用是指明系统中数据是如何流动和变换的,
STD(Status Transfer Diagram,状态-变迁图),用于指明系统在外部事件的作用下将会如何动作,
具体做法是首先将整个系统看成一个加工信息处理装置,是一个黑盒子,标识出系统边界和所有输入输出数据流。然后自顶向下,对加工内部进行细化,逐层分解,将复杂功能分解为若干简单功能的有机组合,绘制数据流图。
● 用一套分层的数据流图; ● 一本数据字典; ● 一组加工说明; ● 补充材料。
在画数据流图时,首先应画出系统的输入数据流和输出数据流,也就是先决定系统的范围,然后再考虑系统的内部,同样,对每一个加工来说也是先画出它们的输入、输出,再考虑这个加工的内部。
子图的输入、输出数据流同父图对应加工的输入、输出数据流必须一致,即父图与子图的平衡。
可从以下几个角度来检查数据流图的正确性: ● 数据守恒; ● 文件的使用; ● 父图和子图的平衡。
对象之间进行通信的结构叫做消息。
一些公司已经认识到:在审查需求文档或其他软件产品上花费1个小时,可节省10个小时的工作时间(Grady, 1994)。
通常将软件设计分为总体设计(又称概要设计)和详细设计(又称过程设计)两个阶段。
总体设计通常又被称为概要设计,是软件设计中的第一个阶段。该阶段的基本任务是: ● 将系统划分成模块; ● 决定每个模块的功能; ● 决定模块的调用关系; ● 决定模块的界面,即模块间传递的数据。
所谓模块的独立性,是指软件系统中每个模块只涉及软件要求的具体的子功能,而和软件系统中其他的模块的接口尽可能简单。
一般模块的独立程度可以由两个定性标准度量,即模块间的耦合性和模块的内聚性。
如果一个模块访问另一个模块,彼此之间是通过数据参数交换输入和输出的信息,就叫数据耦合。
如果一个模块通过传递开关、标志、名字等控制信息,明显地控制选择另一模块的功能,就属于控制耦合,
当模块受软件的外部环境约束,例如,I/O把一个模块连接到指定的设备上时,受其格式及通信协议的约束,就出现较高程度的耦合――外部耦合。
当两个或多个模块通过一个公共数据环境相互作用时,如共享对一个公用区中数据的引用权或修改权,它们之间的耦合称为公共环境耦合。
内容耦合。最高程度的耦合是内容耦合。
内聚是描述一个模块内各个元素之间关系的一个概念,是对各元素彼此结合的紧密程度的一种度量,
偶然内聚。是指模块内各功能段之间不存在有意义的联系。
逻辑内聚,是指把几个逻辑上具有相似的功能段的功能放在一个模块内。
时间内聚是把要求在系统运行的同一时间内处理的元素组合成一个模块。
如果一个模块内处理是相关的,而且必须以特定次序执行,则称这个模块为过程内聚模块。
显然,通信内聚的模块内各功能段有公用的信息区,公用信息使模块内各功能段之间的联系密切。
顺序内聚。顾名思义,这类模块中的各组成部分是顺序执行的。
功能内聚。模块中的各程序段联合起来共同完成一个特定的功能,
体系结构设计通常将系统分解成一组相互作用的子系统,采用方框图表示,每一个方框图代表一个子系统。
随着网络的发展,体系结构的分类不断发生变化,常见的形式有:共享数据的容器模型、共享服务或服务器形式的客户机/服务器模型和分层模型等。
第一类是根据系统的数据流进行设计,称为面向数据流的设计(Data Flow-Oriented Design)或者过程驱动的设计(Process-Driven Design);第二类是根据系统的数据结构进行设计,称为面向数据结构的设计(Data Structure-Oriented Design)或者数据驱动的设计(Data-Driven Design);第三类设计方法是面向对象的设计(Object-Oriented Design)。
结构化设计方法(以下简称SD)通常与数据流图衔接起来使用。用数据流图方法得到的数据流图和数据字典描述需求规格说明书;SD则以数据流图为基础,按照一定的步骤将其映射为软件的模块结构。
结构化设计方法提出了一种图形工具――SC(Structure Chart,结构图),进行软件结构设计。
可以看出,在一个好的软件结构中,模块应具有较高扇入和适当的扇出。
在设计良好的软件结构中,通常顶层的扇出数较大,中间层的扇出数较小,底层的扇入数较大,如图3-33所示的瓮型结构。
面向对象的设计任务需要完成三方面的内容。 (1)系统整体设计。主要完成系统整体结构的设计,包括子系统所应具有的任务和子系统之间的关系。 (2)对象设计。对类和对象模型描述具体化,包括每个对象和类的属性和操作,并为对象和类的属性提供内部数据结构。 (3)消息设计。使用对象之间的协作和行为模型,设计出消息模型。
数据建模是系统内部的静态数据结构,它将完成概念数据模型到物理数据模型的转换,描述的主要工具是E-R图。
详细设计是软件设计中的第二个阶段,该阶段的主要目的是在总体结构设计的基础上,为软件中的每个模块
详细设计是软件设计中的第二个阶段,该阶段的主要目的是在总体结构设计的基础上,为软件中的每个模块确定相应的算法及内部数据结构,获得目标系统具体实现的精确描述,为编码工作做好准备。
详细设计基本决定了最终的程序代码的质量。
详细设计的任务主要有如下5点。
(1)确定每个模块的具体算法。
(2)确定每个模块的内部数据结构及数据库的物理结构。
(3)确定每个模块接口的具体细节。
(4)为每个模块设计一组测试用例。
(5)编写文档,参加复审。
为了能够使模块的逻辑描述清楚准确,在详细设计阶段应遵循下列原则。 (1)将保证程序的清晰度放在首位。
(2)设计过程中应采用逐步细化的实现方法。
(3)选择适当的表达工具。
程序流程图是最早出现且使用较为广泛的算法表达工具之一,能够有效地描述问题求解过程中的程序逻辑结构。
(1)程序流程图中可以随心所欲地使用流程线,容易造成程序控制结构的混乱,与结构化程序设计的思想相违背。 (2)程序流程图难以描述逐步求精的过程,容易导致程序员过早考虑程序的控制流程,而忽略程序全局结构的设计。 (3)程序流程图难以表示系统中的数据结构。
N-S图又称为盒图,它是为了保证结构化程序设计而由Nassi和Shneiderman共同提出的一种图形工具。
N-S图又称为盒图,它是为了保证结构化程序设计而由Nassi和Shneiderman共同提出的一种图形工具。在N-S图中,所有的程序结构均使用矩形框表示,它可以清晰地表达结构中的嵌套及模块的层次关系。
PAD图采用了易于使用的树形结构图形符号,既利于清晰地表达程序结构,又利于修改。
PDL(Process Design Language,过程设计语言)是一种用于描述程序算法和定义数据结构的伪代码。
相对于软件生命周期中的其他阶段,编码阶段的耗费较少且实现难度不大。由于编码完全是在设计基础上进行的,因此,一个程序的优劣主要取决于软件设计的质量,
传统高级语言主要描述问题求解的逻辑过程。
传统高级语言主要描述问题求解的逻辑过程。从不同的应用角度出发,传统高级语言又可分为通用语言和专用语言。通用语言即适合多数应用领域的程序设计语言,例如:BASIC、FORTRAN、C等。
例如:BASIC、FORTRAN、C等。
专用语言则具有很强的针对性,通常是专为某一应用领域软件开发而设计的,
其中,PROLOG语言和LISP语言是专门用于处理人工智能领域问题,APL语言是专门用于解决数组和向量计算问题的,
一些典型调查还表明,一个程序的执行时间,往往有一大部分是耗费在一小部分代码上的。为了提高效率,只需将这一部分代码改用汇编语言,其余代码仍可使用高级语言。
源程序文档化包括选择好的标识符名称、添加注释以及良好的书写格式等。
在编写程序时,还需要注意的是数据说明的风格。
软件测试员用于描述测试方式的两个术语是黑盒测试和白盒测试。
在白盒测试中,软件测试员可以访问程序员的代码,并通过检查代码来协助测试,测试人员必须了解程序的内部结构和处理过程。
这种方法把被测程序的输入域划分为若干等价类,把漫无边际的随机测试变成有针对性的等价类测试。它的出发点是,每一个测试用例都代表了一类与它等价的其他例子。
但如果把测试值选在等价类的边界上,往往有更好的效果,这是边界值分析法的主要思想。
所谓猜错,就是猜测被测程序中哪些地方容易出错,并据此设计测试用例。如果说等价法和边界法均有线索可寻,则猜错法更多地依赖于测试人员的直觉与经验。
因果图法是借助图形来设计测试用例的一种系统方法,特别适用于被测程序具有多种输入条件,程序的输出又依赖于输入条件的各种组合情况。
(2)用因果图表明输入和输出之间的逻辑关系,如图5-2所示。 图5-2 因果图示例 其中,∧代表逻辑与,∨代表逻辑或,~代表逻辑非,1、2、3、4、5为因结点,A、B、C、D为果结点,I1、I2、I3、I4为中间结点。
因果图法的优点是,不论输入条件的组合多么复杂,总可以按上例给出的步骤找出测试用例。
在已经找到软件缺陷的地方再找找的原因是,很多程序员倾向于只修复报告出来的软件缺陷,不多也不少。
逻辑覆盖是一组覆盖方法的总称。按照由低到高对程序逻辑的覆盖程度,又可分为以下几种覆盖: (1)语句覆盖:使被测程序的每条语句至少执行一次; (2)判定覆盖:使被测程序的每一分支至少执行一次,故又称分支覆盖; (3)条件覆盖:要求判定中的每个条件均按“真”、“假”两种结果至少执行一次。
(4)条件组合覆盖:这是覆盖程度比前3种都强的一种覆盖。它与条件覆盖的区别是,它不是简单地要求每个条件都出现“真”与“假”两种结果,而是要求让这些结果的所有可能组合都至少出现一次。
路径测试法是借助程序图设计测试用例的一种白盒方法。在逻辑覆盖法中,测试用例是基于流程图来设计的。
结点覆盖:程序的测试路径至少经过程序图中每个结点一次,相当于逻辑覆盖中的语句覆盖。
边覆盖:程序的测试路径至少经过程序图中的每条边一次。它相当于逻辑覆盖法中的判定覆盖。
同时满足上述两种覆盖的覆盖称为完全覆盖。测试简单程序时,这是最低的覆盖标准。
路径覆盖:这种覆盖的要求是,程序图中每条路径都至少经过一次。
当被测程序含有循环时,穷举测试要求在最大循环次数的范围内,试遍各种不同的循环次数和所有可能的路径,不管这些路径要重复多少次。路径覆盖不需要考虑程序的循环,只要求每条路径至少经过一次。
所以在实际工作中,总是把这些技术结合起来使用,形成综合的测试设计策略,以满足不同测试阶段和不同程序的需要。
在综合测试及其后的测试阶段,除去很小的程序,都采用黑盒方法。
单元测试的设计策略稍有不同。因为在模块设计测试用例时,可以直接参考模块的源程序。所以单元测试的策略,总是把白盒法与黑盒法结合运用。
先仿照上述步骤用黑盒法提出一组基本的测试用例,然后用白盒法做验证。
先用白盒法分析模块的逻辑结果,提出一批测试用例,然后根据模块的功能说明用黑盒法进行补充。
第一步:确定测试策略。
因此可首先用黑盒法设计测试用例,然后用白盒法验证其完整性,必要时再进行补充。
第二步:根据本例的实际情况,在黑盒法中首先可用等价分类法划分输入的等价类,然后用边界值分析法和猜错法做补充。
根据本例的实际情况,在黑盒法中首先可用等价分类法划分输入的等价类,然后用边界值分析法和猜错法做补充。
第三步:提出一组初步的测试用例,如表5-10所示。
第四步:用白盒法验证第三步产生的测试用例的充分性。
单元测试是一系列软件测试的第一步,通常在编码阶段进行。单元一般指程序中的模块或子程序,是程序中最小的独立编译单位。
测试的重点应该放在以下5个方面。 ● 模块的接口; ● 局部数据结构; ● 重要的执行路径; ● 出错处理路径; ● 影响以上各项的边界条件。
完整的单元测试,应包括动态测试及在它以前的全部测试工作。其实施步骤通常为: 编译模块→静态分析→代码复审→动态测试。
可以在单元测试时,为被测模块编一些测试模块,作为它的上级模块或下级模块的替身。代替上级模块的称为驱动模块,代替下级模块的称为桩模块。
模块通过单元测试后,要组装为程序,在组装过程中进行的测试,称为综合测试。
综合测试通常采用黑盒测试策略,其实施策略又分为非渐增式和渐增式两种。
自顶向下测试属于渐增式方式。测试时从顶层模块开始,沿被测程序的结构图逐步下移,每次只增加一个新的模块。
自顶向下测试属于渐增式方式。测试时从顶层模块开始,沿被测程序的结构图逐步下移,每次只增加一个新的模块。按照移动路线的差异,又可分为深度优先和广度优先两种具体做法。
自底向上测试是渐增测试的又一种方式。
混合测试方式的要点如下: (1)对上层模块采取自顶向下测试,使得能够较早显示程序的总体轮廓。 (2)对某些关键模块或子系统采取自底向上组装和测试的方法,以便能够较容易地产生测试用例,减少对模块重复测试的次数。
综合测试完成后,模块已组装为程序,下一步就可以整个程序为对象,进行更高等级的测试。高级测试按测试范围的大小分为:确认测试和系统测试。
确认测试继综合测试之后进行,是测试阶段的第二步工作。其目的是确认所开发的软件是否符合软件需求规格说明书(SRS)的要求。
系统测试的任务,就是要把新开发的软件安装到系统中,检查它能否与系统的其余部分协调运行,完成系统规格说明书中对它提出的要求。
静态分析器用于分析代码而不执行代码的测试,通过扫描被测程序代码,从中找出可能导致错误的逻辑错误或异常,监督程序代码复杂度,以及代码编写是否遵循程序编写的标准等。
动态分析器用来评估正在运行的软件,
Jtest是Parasoft公司推出的一款针对Java语言的自动化白盒测试工具,它通过自动实现Java的单元测试和代码标准校验,来提高代码的可靠性。
Jtest是Parasoft公司推出的一款针对Java语言的自动化白盒测试工具,它通过自动实现Java的单元测试和代码标准校验,来提高代码的可靠性。Jtest先分析每个Java类,然后自动生成Junit测试用例并执行用例,从而实现代码的最大覆盖,并将代码运行时未处理的异常暴露出来;
Mercury Interactive公司的WinRunner是一种企业级的功能测试工具,用于检测应用程序是否能够达到预期的功能及正常运行。
SilkTest是面向Web应用、Java应用和传统的C/S应用,进行自动化的功能测试和回归测试的工具。
TestDirector是业界第一个基于Web的测试管理系统,它可以在公司内部或外部进行全球范围内测试的管理。
所谓反向跟踪,就是从发现有错的地方开始,逐步往前回溯,直到找出错误的根源,这种方法是非常有效的。
演绎法纠错的过程是,首先根据错误症状列举出所有的可能原因。通过仔细的分析,将其中根据不足或不会发生的原因排除掉。
线索。把它们收集起来,分析它们相互间的关系,找出其中的规律,就有可能提出关于错误原因的假设。用这个假设来解释所有的测试结果,如果都能得到圆满的解释,则假设成立,错误根源就找到了。否则应继续提出新的假设,重复上述的过程。 4.测试法 上述的演绎法与归纳法都是以分析为主的纠错方法,不需要在计算机上进行。但当原有的测试结果不够充分,需要收集更多的线索和数据时,就须提出新的测试用例,在机器上做补充测试。这种为纠错而进行的测试,可称为测试纠错,它常与演绎法或归纳法结合使用,也可以单独使用。 测试纠错与测试不同。后者是为了发现错误,着眼点是“面”,要求用较少的测试用例覆盖尽量多的路径;前者是为了找出错误根源,着眼点是“点”,每一
每一测试用例一般仅覆盖测试者感兴趣的少数条件或路径。
在软件项目的第一阶段中,确立项目范围,定义系统边界,明确项目的预期和约束,确定项目的各种活动和结果,计划确定完成项目所需的任务。
给出各项任务之间依赖关系的任务网络图是一
给出各项任务之间依赖关系的任务网络图是一种有向图,该图中用圆表示任务,圆内是任务的名称,有向弧或箭头表示子任务的进行,圆上的数字表明该任务预计的最早开始时间和结束时间,圆下的数字表明该任务预计的最迟开始时间和结束时间,
给出各项任务之间依赖关系的任务网络图是一种有向图,该图中用圆表示任务,圆内是任务的名称,有向弧或箭头表示子任务的进行,圆上的数字表明该任务预计的最早开始时间和结束时间,圆下的数字表明该任务预计的最迟开始时间和结束时间,
有向图,该图中用圆表示任务,圆内是任务的名称,有向弧或箭头表示子任务的进行,圆上的数字表明该任务预计的最早开始时间和结束时间,圆下的数字表明该任务预计的最迟开始时间和结束时间,
为了给每一个任务标明执行时间,可以利用条形图创建项目任务分配图。
生理需求包括对食物、睡眠等的基本要求;安全需求是指对人身安全的需求;社会需求是指某一社会群体的认同感;受尊重需求是来自他人对自己的尊重;自我实现需求体现了个人的发展。
1.面向规模的度量 根据活动输出的量来衡量。通常计算源程序的代码行数或计算目标代码的长度等。
2.面向功能的度量 通过分析软件总的功能有多少,用给定时间内生产出来的有用功能的数量来表示生产率。
固定功能点计数是将具有上述特征的数量的总和乘以一定的权值,