软件工程设计方法专业知识讲座_第1页
软件工程设计方法专业知识讲座_第2页
软件工程设计方法专业知识讲座_第3页
软件工程设计方法专业知识讲座_第4页
软件工程设计方法专业知识讲座_第5页
已阅读5页,还剩73页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

(1)可行性研究与计划(2)需求分析(3)总体设计

(4)详细设计(5)实现(6)集成测试(7)确认测试(8)使用和维护(根据国标《计算机软件开发规范》)下游上游软件设计--将分析模型转换为设计模型数据词典数据流图实体关系图状态转换图加工规格说明控制规格说明数据对象描述过程设计接口设计体系结构设计(总体)数据设计将设计模型金字塔倒立的后果是什么?数据设计体系结构设计接口设计过程设计软件设计是后续开发步骤及软件维护工作的基础。如果没有设计,只能建立一个不稳定的系统结构学习要求明确结构化设计的主要任务、设计步骤、具体方法;了解其他设计方法如Jackson方法的思想及特点具体掌握软件的概要设计及详细设计的基本思想和方法;重点掌握从数据流图导出初始结构图及如何对初始结构图进行改进的方法。6.1模

块6.2

概要设计的基本概念6.3结构化设计(SD方法)概要6.4

块间联系和块内联系6.5

设计技巧6.6从数据流图导出初始结构图6.1模

考核要求:识记:模块的概念及其特性。.分析阶段主要解决软件系统“做什么”。设计阶段主要解决软件系统“怎么做”。如果问题较简单,要求一旦确定了,立刻就可以开始编程。但对大型系统来说,为了保证产品的质量,并使开发工作能顺利进行,我们必须先为编程制订一个周密的计划,这项工作就称为设计(Design),设计实际上是为需求说明书到程序间的过渡架起一座桥梁。软件结构设计的内容:软件系统的结构,包括数据结构、程序结构。程序结构程序结构表明了程序各个部件(模块)的组织情况,是软件的过程表示。

程序系统应由许多较小的单元组成(右图),这种单元可称为模块,即用一个名字可以调用的一段程序语句,也可以暂将它理解成类似“子程序”的概念。结构图反映程序中模块之间的层次调用关系和联系:它以特定的符号表示模块、模块间的调用关系和模块间信息的传递1模块:模块用矩形框表示,并用模块的名字标记它。结构图2模块的调用关系和接口:模块之间用单向箭头联结,箭头从调用模块指向被调用模块。3模块间的信息传递:当一个模块调用另一个模块时,调用模块把数据或控制信息传送给被调用模块,以使被调用模块能够运行。而被调用模块在执行过程中又把它产生的数据或控制信息回送给调用模块。4在模块A的箭头尾部标以一个菱形符号,表示模块A有条件地调用另一个模块B。当一个在调用箭头尾部标以一个弧形符号,表示模块A反复调用模块C和模块D程序的系统结构图信息隐蔽由parnas方法提倡的信息隐蔽是指,每个模块的实现细节对于其它模块来说是隐蔽的。也就是说,模块中所包含的信息(包括数据和过程)不允许其它不需要这些信息的模块使用。一个模块具有输入和输出、功能、内部数据、程序代码等四个特性。输入和输出分别是模块需要的和产生的信息,功能是指模块所做的工作,输入输出和功能构成了一个模块的外貌,即模块的外部特性。模块用程序代码完成它的功能,内部数据是仅供该模块本身引用的数据,内部数据和程序代码是模块的内部特性。对模块的外部环境只需了解它的外部特性就足够了,其内部特性应该是不必了解的。“由外向里”是较合理的一种思考过程、所以应先确定模块的外部特性,再确定其内部特性6.2

概要设计的基本概念考核要求:

识记:

概要设计的基本任务、几种设计方法构成模块的原则。

领会:概要设计的主要工作是完成模块分解,确定系统的模块层次结构。

概要设计(又称总体设计)的基本任务:·将系统划分成模块·决定每个模块的功能·决定模块的调用关系·决定模块的界面,即模块间传递的数据

概要设计的主要工作:

完成模块分解,确定系统的模块层次结构。

概要设计需交付的文档:

▼数据结构的描述部分;▼模块说明部分,它包括模块结构图及每个模块的功能说明。模块结构图(前图)描述了系统的模块组成以及模块间的调用关系,每个模块的功能说明则需描述模块的输入输出及其功能(即“做什么”,不是“怎么做”)。6.3结构化设计(SD方法)概要考核要求:

识记:结构化设计(StructureDesign,简称SD方法)的基本思想、目标、描述方式步骤。结构图中的主要成分。块间联系与块内联系的概念。领会:块间联系和块内联系是衡量模块之间相对独立性的标准。SD方法的目标:建立结构良好的程序系统。评价设计质量的两个标准:块间联系和块内联系。SD遵循的原则:自顶向下,逐步细化模块化抽象化信息隐蔽6.3.1相对独立单一功能的模块结构

SD方法的基本思想:是将系统设计成由相对独立、单一功能的模块组成的结构。用SD方法设计的程序系统,由于模块之间是相对独立的,所以每个模块可以独立地被理解、编程、测试、排错和修改,这就使复杂的研制工作得以简化,此外,模块的相对独立性也能有效地防止错误在模块之间扩散蔓延,因而提高了系统的可靠性。6.3.2块间联系和块内联系块间联系和块内联系是衡量模块之间相对独立性的两个标准(见下图)。

块间联系:指模块之间的联系,它是对模块独立性的直接衡量,块间联系越小就意味着模块的独立性越高,所以这是一个最基本的标准。

块内联系:

指一个模块内部各成分(语句或语句段)之间的联系,块内联系大了,则模块的相对独立性势必会提高。

SD方法的目标是使块间联系尽量小,块内联系尽量大。

6.3.3

描述方式

SD方法使用的描述方式是结构图(下图)描述了程序的模块结构,并反映了块间联系和块内联系等特性。结构图中的主要成分有:

·模块——它用方框表示,方框中写有模块的名字,一个模块的名字应适当地反映这个模块的功能,这就在某种程度上反映了块内联系。·调用——从一个模块指向另一模块的箭头表示前一模块中含有对后一模块的调用。·数据——调用箭头边上的小箭头表示调用时从一个模块传送给另一模块的数据,小箭头也指出了传送的方向。左图(a)的结构图说明模块A含有一个或多个对模块B的调用。A调用B时,A将数据X、Y传送给B,B返回到A时,将数据Z传送给A。如果B将对Y作修改,然后再将Y回送给A。则Y应出现在调用箭头的两边(左图(b)).

左图中的A为B的调用模块或调用者,B为A的被调模块或下层模块。

除上述基本符号外,结构图中可以再加上一些辅助性的符号,如左图表示模块A有条件地调用模块B,并有条件地调用C或D,图中的菱形符号表示一个条件。右图表示模块A循环地调用B和C,弧形箭头表示循环。下页图中带有双竖线的方框表示现成的模块(如程序库中现有的模块),它们不必再另行编写,这种模块总出现在结构图的底层。设计员可根据具体情况决定是否有必要画出这些辅助性的符号。结构图并不一定是树形的,许多程序的结构呈“清真寺”状(左图),即顶是尖的,中间较宽,而底部较窄。如果所使用的高级语言允许递归,则程序结构可以是右图的形状。

应该注意:一个模块在结构图中只能出现一次,否则修改模块结构时就需要修改多处,这容易造成错误。为了避免线条交叉过多,可采用右图的表示方式:在某些地方用圆表示被调用模块。为了便于理解程序的整个结构,设计员应将整个结构图画在一张纸上。

画结构图的一般习惯:输入模块在左,输出模块在右,而计算模块居中。

6.3.4步骤

SD方法可分两步进行:

建立一个满足系统说明书要求的初始结构图。

对结构图作逐步改进,即在结构图中找出块间联系和块内联系尚可改进之处,然后对有关部分的结构作适当的修改,以提高块内联系和减少块间联系。6.4

块间联系和块内联系考核要求:

识记:块间联系的各种类型、块内联系的各种类型。

领会:块间联系的衡量角度、块内联系各种类型的含义和特点。SD方法的设计总则。

应用:模块分解时.使块间联系尽可能小、块内联系尽可能大。

6.4.1

块间联系的各种类型

块间联系的大小一般可从三个角度来衡量:

方式——块间联系是通过怎样的方式进行的。

作用——块间共用的信息是作什么用的。

数量——块间共用信息的多少。

1.联系的方式

块间联系的方式一般有两种:“用过程语句调用”或“直接引用”。用过程语句调用是通过模块的名字调用整个模块,而“直接引用”是指一个模块直接存取另一模块内部的某些信息,这两种方式相比,前者的块间联系较低,而后者的块间联系则很高。图4.11(a)的是某个缺乏经验的设计员设计的结构。模块GETACOMMAND的功能是从终端获取一条命令,为完成该功能,它调用模块READTERMINAL,后者的功能是从终端读入一行字符(LINE),GETACOMMAND对这行字符再进行处理就可得到一条命令。假设系统有多个终端,从哪个终端读呢?READTERMINAL需要终端号。设计员在模块GETACOMMAND中安排了一个单元存放终端号TERMNUM。READTERMINAL执行时引用这个单元,然后从所指终端读入,并将一行字符返回给GETACOMMAND。该图中从模块READTERMINAL内部到模块GETACOMMAND内部的箭头就表示“直接引用”。现在假设系统需要作一个修改,增加一个模块GETADATALINE,其功能是从终端获取一行数据。修改人员意识到应该利用模块READTERMINAL作为子模块,下面有几种修改方案:1)

GETADATALINE在调用READTERMINAL之前,修改GETACOMMAND中的TERMNUM(图4.11(b))。

这样有可能造成错误,因为原先编写GETACOMMAND时不知道会有其他模块修改TERMNUM,因此在GETADATALINE执行后再执行GETACOMMAND时,它就可能使用错误的终端号一TERMNUM。2)如果修改人员意识到上述问题,他可能会在GETADATALINE中先保护TERMINAL的当前值,再设置新的值,然后调用READTERMINAL,返回后再恢复TERMNUM原先的值。但这样做还有问题,因为如果GETADATALINE同GETACOMMAND并行执行(例如在多道程序的环境中),则错误仍然存在;即使没有并行执行的可能性,这种设计亦是隐晦的,将来很容易造成错误。3)修改模块GETACOMMAND,使其每次调用READTERMINAL之前重新设置TERMINAL。但这样修改后,编写GETADATALINE和程序员还必须去修改模块GETACOMMAND而这是一个本应与它无关的模块。另外,如果GETADATALINE同GETACOMMAND并行执行,则错误仍然存在。4)GETADATALINE调用READTERMINAL从前先保护TERMINAL原先值再设置新值,从READTERMINAL返回后再恢复原先值;对GETACOMMAND亦作类似的修改,即调用READTERMINAL之前和之后分别保护或恢复TERMINAL的原先值。这样,如果GETADATALINE的保护或恢复指令有错时,GETADATALINE执行时就会失误。为了解决GETADATALINE的失误,必需去研究其他的模块,也就是说,一个模块的错误可能造成另一个模块执行时失误,因此为解决某个模块的失误,需要到其他模块去找原因。可以想像,这样的排错是极其困难的。5)修改人员另外编写一个读终端模块,不再利用原有的READTERMINAL。现在,因为有两个不同的读终端模块,首先是增加了额外的工作量;第二,如果将来终端的硬件特征有了变化时,程序员必须记着有两个读终端模块要随之作修改。上面的几种修改方案都有各种问题,没有一个是令人满意的。

“直接引用”的缺点:界面不清楚,理解某个模块时必须同时去了解另一模块内部的情况,编程时亦是如此;修改时往往要涉及多个模块;排错时亦必须同时分析几个模块才能找出错误的原因......。总之,“直接引用”使两个模块间出现了密切的联系,致使理解、编程、修改、排错时,这两个模块不能单独处理,造成“分而不解”的局面,两个模块实际上不能成为“独立的”单元。“直接引用”是病态的,它造成极强的块间联系,这种块间联系方式增加了开发工作的难度,使理解、编程、修改、排错等活动都难以进行。图4.11(c)的块间联系方式是用过程语句调用,此时两个模块共用的信息是作为过程语句的参数显式传送的,因而每个模块的输入输出数据明显可见。另外,用过程语句调用是通过引用模块名调用整个模块,而不是像“直接引用”那样,用模块名之外的其他名字引用模块内部个别的信息。对图4.ll的例子,有经验的设计员会认识到造成上述修改难题的根本原因是GETACOMMAND和READTERMINAL之间病态的直接引用,所以原先的设计应该将终端号TERMNUM作为READTERMINAL一个输入参数显式传送给它(图4.11(c))。

2.共用信息的作用模块间共用信息可以作"控制信息"用,也可以做数据用.但是如果混合用则块间联系最高.“混合”型是指一个模块修改另一模块的指令。图4.12(a)中,模块A修改模块B中的指令L,由于从修改一方看来,L是数据,而从被修改一方看来L是指令,所以称为“混合”型,或“数据/控制”型。缺点:如果模块A将L改错了,则模块B执行时会失误,即修改一方的错误,会使被修改一方执行时失误,这样为了解决某个模块的失误,必须到另一模块去寻找致错的原因;另外,在理解、编程、修改时,这两个模块也是难以单独考虑的。所以共用信息作“数据/控制”,其块间联系是很高的。

共用信息作“控制”用的情况有好几种:

一种是一个模块直接转向另一模块内部的某个位置,图4.12(b)中,模块A转向棋块B中的某个位置L,这里L对双方来说都是指令,所以称为“控制”型。这种情况的缺点是:一个模块的内部改动可能对其他模块有直接的影响。如模块B欲将L前的某些指令移到L之后,此时就必需考虑这一改动会给模块A带来什么影响,这样的程序是不易维护的;同样,在理解和编程时,这两个模块也是“分而不解”。图4.12(a)和(b)都是引用了模块名之外的另一个名字(模块的内部名),因而都是病态的。另一种情况是:将控制信号作为参数显式传送到另一模块。图4.13(a)中,模块A将一个参数“平均/最高”传送给模块B,模块B按这个参数的值是“平均”还是“最高”,取出“平均成绩”或取出“最高成绩”回送给模块A。

参数“平均/最高”是一个开关量,它的作用是告诉模块B如何工作。这种设计方案完全是人为地增加了不必要的额外负担,调用模块向被调模块传送“控制”型参数(开关量)的情况是完全可以避免的,图4.13(a)只需改成图4.13(b)就可以了,这里模块A根据需要调用模块B1或B2,即需要取“平均成绩”时调用B1,需要取“最高成绩”时调用B2,这就降低了模块间的联系,使结构也更易理解并更易实现了。3.共用信息的数量程序中的联系是因共享信息造成的,模块间的共用的信息越多则块间的联系越大。

为了提高可理解性、可维护性和可靠性,一个模块最好只引用其调用模块显式传送给它的参数以及它本身的局部变量,这样,模块同系统其他部分的联系就会大大减少。

各类块间联系的特性见下表:

块间联系类型对修改的敏感性可修改性可理解性复用性数据型不一定好好好复合型不一定中中中控制型中差差差公共型差中坏坏内容型坏坏坏坏

模块分解的目的是为了降低复杂性,如果能将一个复杂的大问题,化为几个孤立的小问题,从而可以分而治之、各个击破,就降低了问题的复杂性。

如何达到块间联系尽可能小?

每个模块用过程语句(或函数方式等)调用其他模块。

模块间传送的参数作数据用。

模块间共用的信息(如参数等)尽量少。6.4.2

块内联系的各种类型

块内联系是指一个模块内部各成分之间(如语句之间或语句段之间)的联系。

SD方法的另一个目标是:

块内联系尽量大,即,模块分解时应尽量把相互有密切联系的成分划分在同一模块,而不要把不相关的成分凑到一个模块中。

块内联系常见的类型:

偶然型

特点:组成模块的成分纯属偶然,没有必然联系。图4.14模块T中的三个语句实际上没有任何联系(假定A、B、C、D不在文件CAREDFILE中),但是因为模块P、Q、R、S中都含有这样的语句段,设计员为节省空间将它们放在模块T中。主要缺点:不易修改、模块含义不易理解,难以测试。偶然型块内联系通常是为了节省空间而产生的,所以只要有足够的空间就应避免构造这种模块,免得造成维护时的困难。

逻辑型(Logicalcohesion)特点:将几个逻辑上相似的功能放到一个模块中。模块ABC本身的程序流程图会像图4.15(c)那样:各个功能可以共用某一段程序(事实上就是为了节省这些空间,设计员才构造了这个模块),但对各个功能中不相同的部分,程序必须判别一个开关量后,才能选择执行某一个分支。

主要缺点:难理解、难编程.难修改。“偶然型”和“逻辑型”联系都是很弱的,它们都是为了节省空间,而把没有联系的成分放到一个模块中了。瞬时型

特点:将需要同时执行的成分放在同一模块中。

如初始化模块(为各种变量置初值,打开若干个文件等)或结束模块等。“瞬时型”的块内联系稍强于“逻辑型”的。

通讯型(CommunicationalCohesion)

特点:模块中的成分引用共同的数据。

图4.16中的三个模块都属于这一类,模块A中包含三个部分,这三部分使用同一数据来源产生几个报告,模块B包含两个部分,一部分将输入数据存入,另一部分将输入数据打印;模块C中的两个部分都是对同一文件进行管理。缺点:复用性较差。“通讯型”的块内联系比“顺序型”稍弱,因为各成分的执行次序可以是任意的。

顺序型

特点:模块中某个成分的输出是另一个成分的输入。

图4.17中的两个模块都属于这一类型:模块A读入数据并进行编辑,模块B进行累加并将结果打印。“顺序型”比“通讯型”强,因为无论从数据的角度或执行的先后次序来看,模块中某一部分的执行依赖于另一部分,但是同“功能性”相比,“顺序型”还是相当弱的,因为模块中可能包含了几个功能,也可能仅包含某个功能的一部分。

缺点:复用性较差。

功能型(FunctionalCohesion)

特点:一个模块包括并仅包括为完成某一个具体任务所必需的所有成分。

如:

求平方根

计算每小时工资

计算利息

印出支票

解一个方程

优点:界面比较清晰,易于理解,同其他模块的联系较低。功能型模块也易于测试和维护。复用性较好。例如:见图4.18,从模块A的调用者看来,A的作用是“处理一个命令”,所以它是功能型的,至于模块A是“怎么做”的,它是否又要调用其他模块,它的调用者是不关心,也不知道的。从模块的调用者看来,B的作用是“处理SEND命令”,所以它也是功能型的。同理图中其他的模块也都是功能型的。图4.19,是个求解一元二次方程的程序。从模块A的调用者看来,模块A的功能是“求ax2+bx+c=0的根”,显然,这是一个功能,所以A是功能型的。再看模块B。从它的调用者看来,B的功能是求平方根,所以B也是功能型的。显然,B的内部也有许多细节,但模块A是不必知道的。各类块内联系的特性:块内联系类型块间联系

清晰性

复用性可修改性可理解性功能型好

好顺序型好

好通讯型中

中瞬时型差

中逻辑型坏

差偶然型坏

6.4.3

设计总则SD方法的设计总则是:

·使每个模块执行一个功能。·模块间传送数据型参数。·模块间共用信息尽量少。6.5

设计技巧考核要求:

识记:变换型程序结构、事务型程序结构;作用范围和控制范围;模块的大小;模块的扇出和扇入等概念。

领会:病人监护系统设计中使用的设计技巧。

应用:对初始结构图进行改进。

结构图的改进有两条途径:减少块间联系和提高块内联系。6.5.1

建立了初始结构图之后,就可考虑对结构图作逐步改进,结构图的改进是围绕着SD的总则进行的,即要使每个模块执行一个功能,模块间应传送数据型参数,而且参数尽可能少。设计员可以逐个检查每个模块及其界面,找出可改进的地方。在设计时使用了以下一些技巧:

·减少块间联系,其中用得最多的是减少模块之间传送的参数个数。·消除重复的功能。·消除“管道”性模块。·要考虑将来可能发生的变化。·如果一个模块的篇幅较大,可以从中抽出一些功能构成它的下层模块。·如果一个模块的篇幅较小,可以考虑将它同其调用模块合并。·尽可能研究整张结构图,而不是由几个设计员分别考虑一张结构图的各个部分。·初始结构图也可以暂不满足系统说明书中的某些要求,而在改进过程中使这些要求逐步得到满足,因为越到后面,结构图的“可维护性”越好,局部的改动不会影响整个大局。

从以上讨论可以看出,改进的过程带有很强的试探性,设计员需对各种可能的方案作比较和权衡,设计员的经验也是非常重要的。6.5.2功能型的模块的组成一个功能型的模块应包括以下成分:

·执行某项具体任务的部分。·通知它的调用模块发生了例外情况的部分。·在数据结束时通知调用模块“文件完”的部分。6.5.3

消除重复的功能设计过程中经常会发现几个模块具有相类似的功能,这将给编程、修改带来麻烦。图4.36(a)中,Q1和Q2两个模块具有类似的功能,但又不完全相同,如何将其中重复的部分消去呢?

错误的方法:将Q1和Q2合并成一个模块Q’(图4.36(b)),此时模块Q’是“逻辑型”的。

正确的方法是:

先仔细分析Q1、Q2,找出这两个模块中相同的功能(图4.36(a))中的虚线部分),然后把这个功能分离出来,构成它们的一个公共的下层模块Q(图4.36(c))。如果余下的模块Q‘l或Q’2比较简单,则可以同它们的调用模块X或Y合并,所以图4.36(d)、图4.36(e)的方案都是可能的。

图4.36(c)、(d)、(e)的几个方案消除了重复的功能,而且块内联系较高,块间联系较低。6.5.4

作用范围和控制范围

一个判定的作用范围是指所有受这个判定影响的模块的集合。只要模块中含有一些依赖于这个判定的操作,那么该模块就在这个判定的作用范围之中。如果整个模块是否执行取决于某个判定,则该模块的调用模块也在这个判定的作用范围之中。

一个模块的控制范围包括它本身及其所有的下属模块(即由这个模块管理的整个结构层次),控制范围纯粹是结构方面的特点,而与模块的功能无关。

SD方法认为作用范围应该是控制范围的子集,也就是说,受某个判定影响的所有模块应该在该判定所在模块的管理之下。作用范围和控制范围的4种情况:

作用范围不在控制

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论