1、第3章 软件设计,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,第,3,章软件设计,第3章 软件设计,3.1软件概要设计概述,1.设计软件系统结构(简称软件结构),为了实现目标系统,最终必须设计出组成这个系统的所有程序和数据库(文件),对于程序,则首先进行结构设计,具体方法如下:,(1)采用某种设计方法,将一个复杂的系统按功能划分成模块。,(2)确定每个模块的功能。,(3)确定模块之间的调用关系。,(4)确定模块之间的接口,即模块之间传递的信息。,(5)评价模块结构的质量。,从以上内容看,软件结构的设计是以模块为基础的,在需求分析阶段,通过某种分析方
2、法把系统分解成层次结构。在设计阶段,以需求分析的结果为依据,从实现的角度划分模块,并组成模块的层次结构。,软件结构的设计是概要设计关键的一步,直接影响到详细设计与编码的工作。软件系统的质量及一些整体特性都在软件结构的设计中决定。因此,应由经验丰富的软件人员担任,采用一定的设计方法,选取合理的设计方案。,2.数据结构及数据库设计,对于大型数据处理的软件系统,除了系统结构设计外,数据结构与数据库设计也是重要的。,1)数据结构的设计,逐步细化的方法也适用于数据结构的设计。在需求分析阶段,可通过数据字典对数据的组成、操作约束和数据之间的关系等方面进行描述,确定数据的结构特性,在概要设计阶段要加以细化,
3、详细设计则规定具体的实现细节。在概要设计阶段,宜使用抽象的数据类型。如,“,栈,”,是数据结构的概念模型,在详细设计中可用线性表和链表来实现,“,栈,”,。设计有效的数据结构,将大大简化软件模块处理过程的设计。,2)数据库的设计,数据库的设计指数据存储文件的设计,其主要包括以下几方面的设计:,(1)概念设计。在数据分析的基础上,从用户角度采用自底向上的方法进行视图设计。,一般用ER模型来表示数据模型,这是一个概念模型。ER模型既是设计数据库的基础,也是设计数据结构的基础。IDEF1x技术也支持概念模式,用IDEF1x方法建立系统的信息模型,使模型具有一致性、可扩展性和可变性等特性,同样,该模型
4、可作为数据库设计的主要依据。,(2)逻辑设计。ER模型或IDEF1x模型是独立于数据库管理系统(DBMS)的,要结合具体的DBMS特征来建立数据库的逻辑结构。对于关系型的DBMS来说,将概念结构转换为数据模式、子模式并进行规范,要给出数据结构的定义,即定义所含的数据项、类型、长度及它们之间的层次或相互关系的表格等。,(3)物理设计。对于不同的DBMS,物理环境不同,提供的存储结构与存取方法各不相同。物理设计就是设计数据模式的一些物理细节,如数据项存储要求、存取方式和索引的建立等。,数据库技术是一项专门的技术,本书不作详细的讨论。但开发人员应注意到,在大型数据处理系统的功能分析与设计中,同时要进
5、行数据分析与数据设计。数据库的,“,概念设计,”,与,“,逻辑设计,”,分别对应于系统开发中的,“,需求分析,”,与,“,概要设计,”,,而数据库的,“,物理设计”与模块的“详细设计”相对应。,3.编写概要设计文档,编写概要设计文档的内容如下:,(1)概要设计说明书。,(2)数据库设计说明书:主要给出所使用的DBMS简介,数据库的概念模型、逻辑设计和结果。,(3)用户手册:对需求分析阶段编写的用户手册进行补充。(4)修订测试计划:对测试策略、方法和步骤提出明确要求。,4.评审,在该阶段,对设计部分是否完整地实现了需求中规定的功能、性能等要求,设计方案的可行性、关键的处理及内外部接口定义正确性、
6、有效性以及各部分之间的一致性等,都一一进行评审。,3.1.2软件概要设计文档,概要设计说明书是概要设计阶段结束时提交的技术文档。按国标GB8576-88的计算机软件产品开发文件编制指南规定,软件设计文档可分为,“,概要设计说明书,”,、,“,详细设计说明书,”,和,“,数据库设计说明书,”,。,概要设计说明书的主要内容如下:,(1)引言:编写目的,背景,定义,参考资料。,(2)总体设计:需求规定,运行环境,基本设计概念和处理流程,结构。,(3)接口设计:用户接口,外部接口,内部接口。,(4)运行设计:运行模块组合,运行控制,运行时间。,(5)系统数据结构设计:逻辑结构设计,物理结构设计,数据结
7、构与程序的关系。,(6)系统出错处理设计:出错信息,补救措施,系统恢复设计。,3.2 软件设计的基本原理,3.2.1模块化,模块化的概念在程序设计技术中就出现了。何为模块?模块在程序中是数据说明、可执行语句等程序对象的集合,或者是单独命名和编址的元素,如高级语言中的过程、函数和子程序等。在软件的体系结构中,模块是可组合、分解和更换的单元。模块具有以下几种基本属性:,(1)接口:指模块的输入与输出。,(2)功能:指模块实现什么功能。,(3)逻辑:描述内部如何实现要求的功能及所需的数据。(4)状态:指该模块的运行环境,即模块的调用与被调用关系。,功能、状态与接口反映模块的外部特性,逻辑反映它的内部
8、特性。模块化是指解决一个复杂问题时自顶向下逐层把软件系统划分成若干模块的过程。每个模块完成一个特定的子功能,所有的模块按某种方法组装起来,成为一个整体,完成整个系统所要求的功能。在面向对象设计中,模块和模块化的概念将进一步扩充(详见第 1112 章)。模块化是软件解决复杂问题所具备的手段,为了说明这一点,可将问题的复杂性和工作量的关系进行推理。,设问题x,表示它的复杂性函数为C(x),解决它所需的工作量函数为E(x)。对于问题P1和P2;如果,C(P,1,)C(P,2,),即P,1,比P,2,复杂,那么,E(P,1,)E(P,2,),即问题越复杂,所需要的工作量越大。,根据解决一般问题的经验,
9、规律为:,C(P,1,+P,2,)C(P,1,)+C(P,2,),即一个问题由两个问题组合而成的复杂度大于分别考虑每个问题的复杂度之和。这样,可以推出:,单一功能模块的扇入数大比较好,说明本模块为上层几个模块共享的公用模块,重用率高。,属性有:字符、整型、实型、双精度、指针、数组及结构等类型。,E(P1+P2)E(P1)+E(P2),概要设计说明书的主要内容如下:,处理S2,这样的模块不易理解也不易修改,这是最差的内聚情况。,8 三种基本控制结构的流程图,(1)概念设计。,只有符合和遵守这些原则才能得到高度独立的模块。,(1)如果若干模块之间耦合强度过高,每个模块内功能不复杂,可将它们合并,以
10、减少信息的传递和公共区的引用;,只有符合和遵守这些原则才能得到高度独立的模块。,E(P,1,+P,2,)E(P,1,)+E(P,2,),由此可知,开发一个大而复杂的软件系统,将它进行适当的分解,不但可降低其复杂性,还可减少开发工作量,从而降低开发成本,提高软件生产率,这就是模块化的依据。但是否将系统无限制分割,最后开发软件的工作量就会趋于零?事实上模块划分越多,块内的工作量减少,但模块之间接口的工作量增加了,如图 3.1 所示。从图看出,存在着一个使软件开发成本最小区域的模块数M,虽然目前还不能确定M的准确数值,但在划分模块时,避免数目过多或过少,一个模块的规模应当取决于它的功能和用途。同时,
11、应减少接口的代价,提高模块的独立性。,图 3.1 模块与开发软件成本,3.2.2抽象,抽象是认识复杂现象过程中使用的思维工具,即抽出事物本质的共同特性而暂不考虑它的细节,不考虑其他因素。抽象的概念被广泛应用于计算机软件领域,在软件工程学中更是如此。软件工程实施中的每一步都可以看作是对软件抽象层次的一次细化。在系统定义阶段,软件可作为整个计算机系统的一个元素来对待;在软件需求分析阶段,软件的解决方案是使用问题环境中的术语来描述;从概要设计到详细设计阶段,提象的层次逐步降低,将面向问题的术语与面向实现的术语结合起来描述解决方法,直到产生源程序时到达最低的抽象层次。这是软件工程整个过程的抽象层次。具
12、体到软件设计阶段,又有不同的抽象层次,在进行软件设计时,抽象与逐步求精、模块化密切相关,可帮助定义软件结构中模块的实体,由抽象到具体地分析和构造出软件的层次结构,提高软件的可理解性。,3.2.3信息隐蔽,通过抽象,可以确定组成软件的过程实体。通过信息隐蔽,可以定义和实施对模块的过程细节和局部数据结构的存取限制。所谓信息隐蔽,是指在设计和确定模块时,使得一个模块内包含的信息(过程或数据),对于不需要这些信息的其他模块来说,是不能访问的;,“,隐蔽,”,的意思是,有效的模块化通过定义一组相互独立的模块来实现,这些独立的模块彼此之间仅仅交换那些为了完成系统功能所必需的信息,而将那些自身的实现细节与数
13、据,“,隐藏,”,起来。一个软件系统在整个生存期中要经过多次修改,信息隐蔽为软件系统的修改、测试及以后的维护都带来好处。因此,在划分模块时要采取措施,如采用局部数据结构,使得大多数过程(即实现细节)和数据对软件的其他部分是隐藏的,这样,修改软件时偶然引入的错误所造成的影响只局限在一个或少量几个模块内部,不波及其他部分。,3.2.4模块独立性,为了降低软件系统的复杂性,提高可理解性、可维护性,必须把系统划分成为多个模块,但模块不能任意划分,应尽量保持其独立性。模块独立性指每个模块只完成系统要求的独立的子功能,并且与其他模块的联系最少且接口简单。模块独立性概念是模块化、抽象及信息隐蔽这些软件工程基
14、本原理的直接产物。只有符合和遵守这些原则才能得到高度独立的模块。良好的模块独立性能使开发的软件具有较高的质量。由于模块独立性强,信息隐藏性能好,并完成独立的功能,且它的可理解性、可维护性及可测试性好,必然导致软件的可靠性高。另外,接口简单、功能独立的模块易开发,且可并行工作,有效地提高了软件的生产率。,如何衡量软件的独立性呢?根据模块的外部特征和内部特征,提出了两个定性的度量标准,耦合性和内聚性。,1.耦合性(Coupling),耦合性也称块间联系,指软件系统结构中各模块间相互联系紧密程度的一种度量。模块之间联系越紧密,其耦合性就越强,模块的独立性则越差。模块间耦合高低取决于模块间接口的复杂性
15、调用的方式及传递的信息。模块的耦合性有以下几种类型:,无直接耦合数据耦合标记耦合控制耦合公共耦合内容耦合低耦合性高,(1)无直接耦合:指两个模块之间没有直接的关系,它们分别从属于不同模块的控制与调用,它们之间不传递任何信息。因此,模块间的这种耦合性最弱,模块独立性最高。,(2)数据耦合:指两个模块之间有调用关系,传递的是简单的数据值,相当于高级语言中的值传递。这种耦合程度较低,模块的独立性较高。,(3)标记耦合:指两个模块之间传递的是数据结构,如高级语言中的数组名、记录名和文件名等这些名字即为标记,其实传递的是这个数据结构的地址。两个模块必须清楚这些数据结构,并按要求对其进行操作,这样降低了
16、可理解性。可采用,“,信息隐蔽,”,的方法,把该数据结构以及在其上的操作全部集中在一个模块,就可消除这种耦合,但有时因为还有其他功能的缘故,标记耦合是不可避免的。,(4)控制耦合:指一个模块调用另一个模块时,传递的是控制变量(如开关、标志等),被调模块通过该控制变量的值有选择地执行块内某一功能。因此被调模块内应具有多个功能,哪个功能起作用受其调用模块的控制。,控制耦合增加了理解与编程及修改的复杂性,调用模块必须知道被调模块内部的逻辑关系,即被调模块处理细节不能,“,信息隐藏,”,,降低了模块的独立性。,在大多数情况下,模块间的控制耦合并不是必需的,可以将被调模块内的判定上移到调用模块中去,同时
17、将被调模块按其功能分解为若干单一功能的模块,将控制耦合改变为数据耦合。,(5)公共耦合:指通过一个公共数据环境相互作用的那些模块间的耦合。公共数据环境可以是全程变量或数据结构、共享的通信区、内存的公共覆盖区及任何存储介质上的文件和物理设备等(也有将共享外部设备分类为外部耦合的)。,公共耦合的复杂程度随耦合模块的个数增加而增加。如果只有两个模块之间有公共数据环境,那么这种公共耦合就有两种情况:,一个模块只是给公共数据环境送数据,另一个模块只是从公共环境中取数据,这只是数据耦合的一种形式,是比较松散的公共耦合;,两个模块都既往公共数据环境中送数据,又从里面取数据,这是紧密的公共耦合。,如果在模块之
18、间共享的数据很多,且通过参数的传递很不方便时,才使用公共耦合,因为公共耦合会引起以下问题:,耦合的复杂程度随模块的个数增加而增加,无法控制各个模块对公共数据的存取,若某个模块有错,可通过公共区将错误延伸到其他模块,则会影响到软件的可靠性。,使软件的可维护性变差。若某一模块修改了公共区的数据,则会影响到与此有关的所有模块。,降低了软件的可理解性。因为各个模块使用公共区的数据,使用方式往往是隐含的,某些数据被哪些模块共享,不易很快搞清。,(6)内容耦合:是最高程度的耦合,也是最差的耦合。当一个模块直接使用另一个模块的内部数据,或通过非正常入口而转入另一个模块内部时,这种模块之间的耦合便为内容耦合。
19、这种情况往往出现在汇编程序设计中。,以上 6 种由低到高的耦合类型,为设计软件、划分模块提供了决策准则。提高模块独立性、建立模块间尽可能松散的系统,是模块化设计的目标。为了降低模块间的耦合度,可采取以下几点措施:,(1)在耦合方式上降低模块间接口的复杂性。模块间接口的复杂性包括模块的接口方式、接口信息的结构和数量。接口方式不采用直接引用(内容耦合),而采用调用方式(如过程语句调用方式)。接口信息通过参数传递且传递信息的结构尽量简单,不用复杂参数结构(如过程、指针等类型参数),参数的个数也不宜太多,如果很多,可考虑模块的功能是否庞大复杂。,(2)在传递信息类型上尽量使用数据耦合,避免控制耦合,慎
20、用或有控制地使用公共耦合。这只是原则,耦合类型的选择要根据实际情况综合地考虑。,2.内聚性(Cohesion),内聚性也称块内联系,指模块的功能强度的度量,即一个模块内部各个元素彼此结合的紧密程度的度量。若一个模块内各元素(语句之间、程序段之间)联系的越紧密,则它的内聚性就越高。内聚性有以下几种类型:,偶然内聚逻辑内聚时间内聚通信内聚顺序内聚功能内聚低内聚性高,(1)偶然内聚:指一个模块内的各处理元素之间没有任何联系。例如,有一些无联系的处理序列在程序中多次出现或在几个模块中都出现,如:,Read disk File;,Calculate current values;,Produce use
21、r output;,为了节省存储,把它们抽出来组成一个新的模块,这个模块就属于偶然内聚。这样的模块不易理解也不易修改,这是最差的内聚情况。,(2)逻辑内聚:指模块内执行几个逻辑上相似的功能,通过参数确定该模块完成哪一个功能。如产生各种类型错误的信息输出放在一个模块,或从不同设备上的输入放在一个模块,这是一个单入口多功能模块。这种模块内聚程度有所提高,各部分之间在功能上有相互关系,但不易修改;,当某个调用模块要求修改此模块公用代码时,而另一些调用模块又不要求修改。另外,调用时需要进行控制参数的传递,造成模块间的控制耦合,调用此模块时,不用的部分也占据了主存,降低了系统效率。,(3)时间内聚:把需
22、要同时执行的动作组合在一起形成的模块为时间内聚模块。如初始化一组变量,同时打开若干文件,同时关闭文件等,都与特定时间有关。时间内聚比逻辑内聚程度高一些,因为时间内聚模块中的各部分都要在同一时间内完成。但是由于这样的模块往往与其他模块联系的比较紧密,如初始化模块对许多模块的运行有影响,因此和其他模块耦合的程度较高。,(4)通信内聚:指模块内所有处理元素都在同一个数据结构上操作(有时称之为信息内聚),或者指各处理使用相同的输入数据或者产生相同的输出数据。如一个模块完成,“,建表,”,、,“,查表,”,两部分功能,都使用同一数据结构,名字表。又如一个模块完成生产日报表、周报表和月报表,都使用同一数据
23、日产量。,通信内聚的模块各部分都紧密相关于同一数据(或者数据结构),所以内聚性要高于前几种类型。同时,可把某一数据结构、文件及设备等操作都放在一个模块内,可达到信息隐藏。,(5)顺序内聚:指一个模块中各个处理元素都密切相关于同一功能且必须顺序执行,前一功能元素的输出就是下一功能元素的输入。,例如,某一模块完成求工业产值的功能,前面部分功能元素求总产值,随后部分的功能元素求平均产值,显然,该模块内两部分紧密相关。,(6)功能内聚:是最强的内聚,指模块内所有元素共同完成一个功能,缺一不可。因此,模块不能再分割,如,“,打印日报表,”,这样一个单一功能的模块。功能内聚的模块易理解、易修改,因为它的
24、功能是明确的、单一的,因此与其他模块的耦合是弱的。功能内聚的模块有利于实现软件的重用,从而提高软件开发的效率。,耦合性与内聚性是模块独立性的两个定性标准,将软件系统划分模块时,尽量做到高内聚低耦合,提高模块的独立性,为设计高质量的软件结构奠定基础。但也有内聚性与耦合性发生矛盾的时候,为了提高内聚性而可能使耦合性变差,在这种情况下,建议给予耦合性以更高的重视。,3.3 软件结构准则,软件结构图是软件系统的模块层次结构,反映了整个系统的功能实现,即将来程序的控制层次体系。对于一个“问题”,可用不同的软件结构来解决,不同的设计方法和不同的划分和组织,可得出不同的软件结构。,软件结构往往用树状或网状结
25、构的图形来表示。软件工程中,一般采用70年代中期 Yourdon等提出的称为结构图(Structure Chart,简称SC)的工具来表示软件结构。结构图的主要内容有:,(1)模块:用方框表示,并用名字标识该模块,名字应体现该模块的功能。,(2)模块的控制关系:两个模块间用单向箭头或直线连接起来表示它们的控制关系,如图 3.2 所示。按照惯例,总是图中位于上方的模块调用下方的模块,所以不用箭头也不会产生二义性。调用模块和被调用模块的关系称为上属与下属的关系,或者称为,“,统率,”,与,“,从属,”,的关系。如图 3.4 所示,模块M统率模块A、B、C,模块D从属于模块A,也从属于M。,(3)模
26、块间的信息传递:模块间还经常用带注释的短箭头表示模块调用过程中来回传递的信息。有时箭头尾部带空心圆的表示传递的是数据,带实心圆的表示传递的是控制信息,如图 3.2 所示。,图 3.2 模块间的控制关系及信息传递,(4)两个附加符号:表示模块有选择调用或循环调用,如图 3.3 所示。,(5)结构图的形态特征。结构图的形态特征包括:,深度:指结构图控制的层次,也是模块的层数,见图 3.4,结构图的深度为5。,宽度:指一层中最大的模块个数,如图 3.4 所示,宽度为 8。,扇出:一个模块直接下属模块的个数,如图 3.4 所示,模块M的扇出为 3。,3.3 选择调用和循环调用的表示,(a)选择调用;(
27、b)循环调用,图 3.4 结构图示例,扇入:指一个模块直接上属模块的个数,如图 3.4 所示,模块T的扇入为 4。,(6)画结构图应注意的事项如下:,同一名字的模块在结构图中仅出现一次。,调用关系只能从上到下。,不严格表示模块的调用次序,习惯上从左到右。有时为了减少连线的交叉,适当地调整同一层模块左右位置,以保持结构图的清晰性。,3.3.2软件结构设计优化准则,软件概要设计的主要任务就是软件结构的设计,为了提高设计的质量,必须根据软件设计的原理改进软件设计,并提出以下软件结构的设计优化准则。,1.模块独立性准则,划分模块时,尽量做到高内聚,低耦合,保持模块相对独立性,并以此原则优化初始的软件结
28、构。,(1)如果若干模块之间耦合强度过高,每个模块内功能不复杂,可将它们合并,以减少信息的传递和公共区的引用;,(2)若有多个相关模块,应对它们的功能进行分析,消去重复功能。,2.控制范围与作用范围之间的准则,一个模块的作用范围应在其控制范围之内,且条件判定所在的模块应与受其影响的模块在层次上尽量靠近。,在软件结构中,由于存在着不同事务处理的需要,某一层上的模块会存在着判断处理,这样可能影响其他层的模块处理。为了保证含有判定功能模块的软件设计的质量,引入了模块的作用范围(或称影响范围)与控制范围的概念。,一个模块的作用范围指受该模块内一个判定影响的所有模块的集合。一个模块的控制范围指模块本身以
29、及其所有下属模块(直接或间接从属于它的模块)的集合。,在设计阶段,以需求分析的结果为依据,从实现的角度划分模块,并组成模块的层次结构。,ENDCASE,一个模块的控制范围指模块本身以及其所有下属模块(直接或间接从属于它的模块)的集合。,(a)选择调用;,具体到软件设计阶段,又有不同的抽象层次,在进行软件设计时,抽象与逐步求精、模块化密切相关,可帮助定义软件结构中模块的实体,由抽象到具体地分析和构造出软件的层次结构,提高软件的可理解性。,(1)无直接耦合:指两个模块之间没有直接的关系,它们分别从属于不同模块的控制与调用,它们之间不传递任何信息。,提高模块独立性、建立模块间尽可能松散的系统,是模块
30、化设计的目标。,处理S2,对处理过程的算法和数据库的物理结构都要评审。,从示例可以看到PDL的总体结构与一般程序完全相同。,另外,接口简单、功能独立的模块易开发,且可并行工作,有效地提高了软件的生产率。,ELSE ENDIF,为了降低软件系统的复杂性,提高可理解性、可维护性,必须把系统划分成为多个模块,但模块不能任意划分,应尽量保持其独立性。,在面向对象设计中,模块和模块化的概念将进一步扩充(详见第 1112 章)。,(5)顺序内聚:指一个模块中各个处理元素都密切相关于同一功能且必须顺序执行,前一功能元素的输出就是下一功能元素的输入。,IDEF1x技术也支持概念模式,用IDEF1x方法建立系统
31、的信息模型,使模型具有一致性、可扩展性和可变性等特性,同样,该模型可作为数据库设计的主要依据。,结构图的形态特征包括:,如图 3.5(a)(符号表示模块内有判定功能,阴影表示模块的作用范围)所示,模块D的作用范围是C、D、E和F,模块D的控制范围是D、E、F,作用范围超过了控制范围,这种结构最差。因为D的判定作用到了C,必然有控制信息通过上层模块B传递到C,这样增加了数据的传递量和模块间的耦合。若修改D模块,则会影响到不受它控制的C模块,这样不易理解与维护。再看图 3.5(b),模块TOP的作用范围在控制范围之内,但是判定所在模块与受判定影响的模块位置太远,也存在着额外的数据传递(模块B、D并
32、不需要这些数据),增加了接口的复杂性和耦合强度。这种结构虽符合设计原则,但不理想。,图 3.5模块的判定作用范围,(a)差的结构图;(b)不理想的结构图;(c)理想的结构图,最理想的结构图是图3.5(c),消除了额外的数据传递。如果在设计过程中,发现模块作用范围不在其控制范围之内,可以用以下方法加以改进:,(1)上移判断点。如图 3.5(a)所示,将模块D中的判断点上移到它的上层模块B中,或者将模块D整个合并到模块B中,使该判断的层次升高,以扩大它的控制范围。,(2)下移受判断影响的模块。将受判断影响的模块下移到判断所在模块的控制范围内,如图 3.5(a)所示,将模块C下移到模块D的下层。,3
33、软件结构的形态特征准则,软件结构的深度、宽度、扇入及扇出应适当。,深度是软件结构设计完成后观察到的情况,能粗略地反映系统的规模和复杂程度,宽度也能反映系统的复杂情况。,宽度与模块的扇出有关,一个模块的扇出太多,说明本模块过分复杂,缺少中间层。单一功能模块的扇入数大比较好,说明本模块为上层几个模块共享的公用模块,重用率高。但是不能把彼此无关的功能凑在一起形成一个通用的超级模块,虽然它扇入高,但低内聚。因此非单一功能的模块扇入高时应重新分解,以消除控制耦合的情况。软件结构从形态上看,应是顶层扇出数较高一些,中间层扇出数较低一些,底层扇入数较高一些。,4.模块的大小准则,在考虑模块的独立性同时,为
34、了增加可理解性,模块的大小最好在50150条语句左右,可以用12页打印纸打印,便于人们阅读与研究。,5.模块的接口准则,模块的接口要简单、清晰及含义明确,便于理解,易于实现、测试与维护。,这里介绍的几条优化准则是人们在开发软件的长期实践中所积累的经验而总结出的一些启发式准则,本书第8章介绍的结构化设计方法和第 11、12 章介绍的面向对象设计方法都遵循这些准则。这些准则能给予软件开发人员有益的启示,对改进设计结构,提高软件质量有重要的参考价值。,3.3.3表示软件结构的HIPO图,HIPO图(Hierarchy Plus Input/Processing/Output)是 IBM公司70年代发
35、展起来的表示软件系统结构的工具。它既可以描述软件总的模块层次结构H图(层次图),又可以描述每个模块输入/输出数据、处理功能及模块调用的详细情况IPO图。HIPO图以模块分解的层次性以及模块内部输入、处理及输出三大基本部分为基础建立的。当然,绘制HIPO图同样要遵循软件设计的基本原理。,1.HIPO图的H图,该图用于描述软件的层次结构,矩形框表示一个模块,矩形框之间的直线表示模块之间的调用关系,同结构图一样未指明调用顺序。在 2.4.2 节的IDEF方法应用示例的销售管理系统中,它的H图如图 3.6 所示。,图 3.6 销售管理系统的H图,2.IPO图,H图只说明了软件系统由哪些模块组成及其控制
36、层次结构,并未说明模块间的信息传递及模块内部的处理。因此对一些重要模块还必须根据数据流图、数据字典及H图绘制具体的IPO图,图 3.7 为,“,确定能否供货,”,的IPO图。,“,确定能否供货,”,是图 3.6 中的一个模块。,3.4 基于IDEF0图的设计方法,基于IDEF0图的设计也是结构化设计技术之一,它以系统的功能模型和信息结构为基础设计系统的软件结构。由于IDEF0图按照自顶向下逐层对系统进行分解,并且对系统的每一功能的输入、输出、约束和机制都进行了全面的描述。因此,在系统概要设计时,一般按照IDEF0图的分解层次,逐层将其转换成软件结构图。对于某一层的IDEF0图按以下方法转换:,
37、1)找出该层IDEF0图的父图,搞清父、子图之间的输入/输出、控制关系。,(2)以父图的活动为上层模块,子图中的活动为下层模块,画出系统的单层结构图。,(3)根据IDEF0图各个活动的输入/输出数据、控制信息及数据库的结构、数据项定义等,确定模块的接口。,(4)综合所有层次的结构图,得到系统初始的软件结构图。(5)根据软件结构的优化准则进行精化。,在由IDEF0图导出初始软件结构图的过程中,往往将一个活动方框对应于一个处理模块。应反复地理解全部IDEF0图的内容和含义,对最初形成的模块结构进行必要的调整、修改、分解或合并,最终的软件结构与基于DFD图设计的软件结构(见第8章)不会有太大的差别
38、3.5 软件详细设计,1.算法设计,用某种图形、表格、语言等工具将每个模块处理过程的详细算法描述出来。,2.数据结构设计,对于需求分析、概要设计确定的概念性的数据类型进行确切的定义。,3.物理设计,对数据库进行物理设计,即确定数据库的物理结构。,物理结构主要指数据库的存储记录格式、存储记录安排和存储方法,这些都依赖于具体所使用的数据库系统。,4.其他设计,根据软件系统的类型,还可能要进行以下设计:,(1)代码设计:为了提高数据的输入、分类、存储及检索等操作的效率,以及节约内存空间,对数据库中的某些数据项的值要进行代码设计。,(2)输入/输出格式设计。,(3)人机对话设计:对于一个实时系统,
39、用户与计算机频繁对话,因此要进行对话方式、内容及格式的具体设计。,5.编写详细设计说明书,详细设计说明书有下列的主要内容:,(1)引言:包括编写目的、背景、定义、参考资料。,(2)程序系统的组织结构。,(3)程序1(标识符)设计说明:包括功能、性能、输入、输出、算法、流程逻辑、接口。,(4)程序2(标识符)设计说明。,(5)程序N(标识符)设计说明。,6.评审,对处理过程的算法和数据库的物理结构都要评审。,3.5.2 详细设计方法,处理过程设计中采用的典型方法是结构化程序设计(SP)方法,最早是由E.W.Dijkstra在 20 世纪 60 年代中期提出的。详细设计并不是具体地编程序,而是已经
40、细化成很容易从中产生程序的图纸。因此详细设计的结果基本决定了最终程序的质量。为了提高软件的质量,延长软件的生存期,软件的可测试性、可维护性是重要保障。软件的可测试性、可维护性与程序的易读性有很大关系。详细设计的目标不仅是逻辑上正确地实现每个模块的功能,还应使设计出的处理过程清晰易读。结构化程序设计是实现该目标的关键技术之一,它指导人们用良好的思想方法开发易于理解、易于验证的程序。结构化程序设计方法有以下几个基本要点。,1.采用自顶向下、逐步求精的程序设计方法,在需求分析、概要设计中,都采用了自顶向下、逐层细化的方法。使用,“,抽象,”,这个手段,上层对问题抽象、对模块抽象和对数据抽象,下层则进
41、一步分解,进入另一个抽象层次。在详细设计中,虽然处于,“,具体,”,设计阶段,但在设计某个模块内部处理过程中,仍可以逐步求精,降低处理细节的复杂度。,2.使用三种基本控制结构构造程序,任何程序都可由顺序、选择及重复三种基本控制结构构造。这三种基本结构的共同点是单入口、单出口。它不但能有效地限制使用GOTO语句,还创立了一种新的程序设计思想、方法和风格,同时为自顶向下、逐步求精的设计方法提供了具体的实施手段。如对一个模块处理过程细化时,开始是模糊的,可以用下面三种方式以模糊过程进行分解:,(1)用顺序方式对过程分解,确定各部分的执行顺序。,(2)用选择方式对过程分解,确定某个部分的执行条件。(3
42、)用循环方式对过程分解,确定某个部分进行重复的开始和结束的条件。,对处理过程仍然模糊的部分反复使用以上分解方法,最终可将所有细节确定下来。,3.主程序员的组织形式,主程序员的组织形式指开发程序的人员应采用以一个主程序员(负责全部技术活动)、一个后备程序员(协调、支持主程序员)和一个程序管理员(负责事务性工作,如收集、记录数据,文档资料管理等)三人为核心,再加上一些专家(如通信专家、数据库专家)、其他技术人员组成小组。,这种组织形式突出了主程序员的领导,设计责任集中在少数人身上,有利于提高软件质量,并且能有效地提高软件生产率。这种组织形式最先由IBM公司实施,随后其他软件公司也纷纷采用主程序员制
43、的工作方式。,因此,结构化程序设计方法是综合应用这些手段来构造高质量程序的思想方法。,3.6 软件详细设计表示法,3.6.1程序流程图,程序流程图又称为程序框图,它是 最悠久、使用最广泛的一种描述程序逻辑结构的工具,图 3.8 为流程图的三种基本控制结构。,流程图的优点是直观清晰、易于使用,是开发者普遍采用的工具,但是它有如下严重缺点:,(1)可以随心所欲地画控制流程线的流向,容易造成非结构化的程序结构,编码时势必不加限制地使用GOTO语句,导致基本控制块多入口多出口,这样会使软件质量受到影响与软件设计的原则相违背。,图 3.8 三种基本控制结构的流程图,(2)流程图不能反映逐步求精的过程,往
44、往反映的是最后的结果。,(3)不易表示数据结构。,为了克服流程图的缺陷,要求流程图都应由三种基本控制结构顺序组合和完整嵌套而成,不能有相互交叉的情况,这样的流程图是结构化的流程图。,3.6.2 PAD,图PAD图指问题分析图(Problem Analysis Diagram),是 日立公司于1979年提出的一种算法描述工具,它是一种由左往右展开的二维树型结构。PAD图的基本控制结构如图 3.9 所示。,PAD图的控制流程为自上而下、从左到右地执行。图 3.10 给出了将数组A(1)到A(10)进行选择法排序的算法描述的PAD图。从图 3.10 给出的例子可以看出PAD图的优点如下:,(1)清晰
45、地反映了程序的层次结构。图中的竖线为程序的层次线,最左边竖线是程序的主线,其后一层一层展开,层次关系一目了然。,图 3.9 PAD的基本控制结构,图 3.10 PAD图的示例,(2)支持逐步求精的设计方法,左边层次中的内容可以抽象,然后由左到右逐步细化。,(3)易读易写,使用方便。,(4)支持结构化的程序设计原理。,(5)可自动生成程序。PAD图有对照FORTRAN,Pascal,C等高级语言的标准图式。因此在有PAD系统的计算机上(如日立公司的M系列机),可以直接输入PAD图,由机器自动通过遍历树的办法生成相应的源代码,大大提高了软件的生产率。PAD图为软件的自动化生成提供了有力的工具。,3
46、6.3过程设计语言,过程设计语言(Process Design Language,简称PDL)是在伪码的基础上,扩充了模块的定义与调用、数据定义和输入输出而形成的。它的控制结构与伪码相同。PDL是一种用于描述模块算法设计和处理细节的语言。PDL与在 8.5 节中介绍的结构化语言的结构相似,一般分为内外两层语法,外层语法应符合一般程序设计语言常用的语法规则,而内层语法则用一些简单的句子、短语和通用的数学符号,来描述程序应执行的功能。PDL具有严格的关键字外层语法,用于定义控制结构、数据结构和模块接口,而它表示实际操作和条件的内层语法又是灵活自由的,使用自然语言的词汇。,PDL与结构化分析中描述
47、加工逻辑的,“,结构化语言,”,有什么不同呢?所不同的仅是它们的作用不同,故抽象层次不同,模糊程度不同。,“,结构化语言,”,是描述加工,“,做什么,”,的,并且使开发人员和用户都能看懂,因此无严格的外语法,内层自然语言描述较抽象、较概括。而PDL是描述处理过程,“,怎么做,”,的细节。开发人员将按其处理细节编程序,故外层语法更严格一些,更趋于形式化,内层自然语言描述实际操作更具体更详细一些。,1.PDL特点,PDL的特点如下:,(1)所有关键字都有固定语法,以便提供结构化控制结构、数据说明和模块的特征。,(2)描述处理过程的说明性语言没有严格的语法。,(3)具有数据说明机制,包括简单的与复杂
48、的数据说明。(4)具有模块定义和调用机制,开发人员应根据系统编程所用的语种,说明PDL表示有关程序结构。,2.程序结构,用PDL表示的程序结构一般有下列几种结构。,1)顺序结构,采用自然语言描述顺序结构:,处理S1,处理S2,处理Sn,2)选择结构,(1)IF-结构:,IF 条件 IF 条件,处理S,1,或 处理S,ELSE ENDIF,处理S,2,ENDIF,(2)IF-ORIF-ELSE结构:,IF 条件1,处理S,1,ORIF 条件,2,ELSE 处理Sn,ENDIF,(3)CASE结构:,CASE OF,CASE(1),处理S,1,CASE(2),处理S,2,ELSE 处理S,n,EN
49、DCASE,3)重复结构,(1)FOR 结构:,FOR i=1 TO n,循环体,END FOR,(2)WHILE 结构:,WHILE 条件,循环体,ENDWHILE,(3)UNTIL 结构:,REPEAT,循环体,UNTIL 条件,4)出口结构,(1)ESCAPE 结构(退出本层结构):,WHILE 条件,处理S1,ESCAPE L IF 条件,处理S,2,ENDWHILE,L:,(2)CYCLE结构(循环内部进入循环的下一次):,L:WHILE 条件,处理S,1,CYCLE L IF 条件,处理S,2,ENDWHILE,5)扩充结构,(1)模块定义:,PROCEDURE 模块名(参数),R
50、ETURN,END,(2)模块调用:,CALL 模块名(参数),(3)数据定义:,DECLARE 属性 变量名,,属性有:字符、整型、实型、双精度、指针、数组及结构等类型。,(4)输入/输出:,GET(输入变量表),PUT(输出变量表),3.PDL应用示例,现以系统主控模块详细设计为例,说明如何用PDL来描述。,PROCEDURE模块名(),清屏;,显示系统用户界面;,PUT(,“,请输入用户口令:,”,);,GET(password);,IF password系统口令,提示警告信息;,退出运行,ENDIF,显示本系统主菜单;,WHILE(true),接收用户选择ABC;,IF ABC=,“,






