《《软件工程导论》第五章总体设计.ppt》由会员分享,可在线阅读,更多相关《《软件工程导论》第五章总体设计.ppt(133页珍藏版)》请在三一办公上搜索。
1、总体设计,第五章,山东师范大学信息科学与工程学院 王化雨,09-10 学 年 第 一 学 期张海藩软件工程导论(第5版),2009年10月,2023/6/1,2,主要内容,概述设计过程设计原理启发规则描述软件结构的图形工具面向数据流的设计方法,2023/6/1,3,将分析模型转换为设计,数据词典,状态转换图,过程设计,接口设计,体系结构设计,数据设计,2023/6/1,4,软件设计是后续开发步骤及软件维护工作的基础。如果没有设计,只能建立一个不稳定的系统结构,软件设计的必要性,2023/6/1,5,软件设计的两个阶段,从工程管理的角度来看,软件设计分两步完成。概要设计,将软件需求转化为数据结构
2、和软件的系统结构。详细设计,即过程设计。通过对结构表示进行细化,得到软件的详细的数据结构和算法。,2023/6/1,6,总体设计的任务,经过需求分析,系统必须“做什么”已经清楚了,现在要决定“怎样做”。总体设计又称为概要设计或初步设计。总体设计的任务:划分出组成系统的物理元素:程序、文件、数据库、人工过程、文档等。设计软件的结构,即确定系统中每个程序是由哪个模块组成,模块间的关系如何。,2023/6/1,7,总体设计的步骤,以需求分析中得到的数据流图为基础,寻找实现目标系统的各种不同方案;为其中每一个合理方案,准备一份系统流程图,列出组成系统的所有物理元素,进行成本/效益分析,并制定实现方案的
3、进度计划;分析员应综合分析比较这些合理的方案,从中选择一个最佳方案向用户推荐;对于用户接受的方案,分析员应多方改进,进行必要的数据库设计,确定测试要求并制定测试计划。,2023/6/1,8,总体设计的必要性,可以站在全局的高度,花较少成本,从较抽象的层次上分析对比多种可能的系统实现方案和软件结构,从中选出最佳方案和最合理的软件结构,从而用较低成本开发出较高质量的软件系统。,2023/6/1,9,主要内容,概述设计过程设计原理启发规则描述软件结构的图形工具面向数据流的设计方法,2023/6/1,10,总体设计的阶段,通常由两个主要阶段组成:系统设计阶段,确定系统的具体设计方案;结构设计阶段,确定
4、软件结构。,2023/6/1,11,总体设计的9个步骤,设想供选择的方案选取合理的方案推荐最佳方案功能分解设计软件结构,设计数据库制定测试计划书写文档审查和复审,2023/6/1,12,1.设想供选择的方案,在总体设计阶段分析员应该考虑各种可能的实现方案,并且力求从中选出最佳方案。开始时只有系统的逻辑模型,分析员有充分的自由分析比较不同的物理实现方案,一旦选出了最佳的方案,将能大大提高系统的性能/价格比。需求分析阶段得出的数据流图是总体设计的极好的出发点。设想供选择的方案的一种常用的方法是:设想把数据流图中的处理分组的各种可能方法,抛弃在技术上行不通的方法;余下的分组方法代表可能的实现策略,并
5、且可以启示供选择的物理系统。,2023/6/1,13,2.选择合理的方案,应该从前一步得到的一系列供选择的方案中选取若干个合理的方案:通常,选取的这些方案中至少应包括低成本、中成本和高成本的三种方案类型。在判断哪些方案合理时应该考虑在前面的问题定义、可行性研究、需求分析阶段确定的工程规模和目标。必要时需要进一步征求用户的意见。对每个合理方案,分析员都要准备4方面资料:系统流程图;组成系统的物理元素清单;成本效益分析;实现这个系统的进度计划。,2023/6/1,14,3.推荐最佳方案,分析员应该:综合分析对比各种合理方案的利弊选择一个最佳方案向用户推荐为推荐的方案制定详细的实现计划对于分析员推荐
6、的最佳方案:用户和有关专家应该认真审查。如果确认该方案确实符合用户的需要,并且在现有条件下完全能够实现,则应该提请使用部门负责人进一步审批。在使用部门负责人也接受了分析员所推荐的方案之后,方可进入总体设计过程的下一步工作,即结构设计阶段。,2023/6/1,15,4.功能分解,为了实现目标系统,必须设计出组成这个系统的所有程序和文件。对于程序(特别是复杂的大型程序)的设计,通常分为两个阶段:结构设计:确定系统由哪些模块组成,以及这些模块之间的相互关系。过程设计:确定每个模块的处理过程。其中,结构设计是总体设计阶段的任务,而过程设计则是详细设计阶段的任务。为确定软件结构:首先需要从实现角度把复杂
7、的功能进一步分解。分析员结合算法描述仔细分析数据流图中的每个过程,如果一个处理的功能过分复杂,必须把它的功能适当地分解。分解后的每个功能对大多数程序员而言都是明显易懂的。功能分解导致数据流图的进一步细化,同时还应该用IPO图或其他适当工具简要描述细化后每个处理的算法。,2023/6/1,16,5.设计软件结构,通常程序中,一个模块完成一个适当的子功能。应该把模块组织成良好的层次系统,顶层模块调用它的下层模块以实现程序的完整功能,每个下层模块再调用更下层的模块,从而完成程序的一个子功能,最下层的模块完成最具体的功能。软件结构(即由模块组成的层次系统)可以用层次图(不是层次方框图)或结构图来描绘。
8、如果数据流图细化到适当层次,则可直接从数据流图映射出软件结构,即面向数据流的设计方法。,2023/6/1,17,6.设计数据库,数据库的应用越来越广泛,目前大多数的系统都要用到数据库技术。数据库设计是一项专门的技术,包括模式设计、子模式设计、完整性和安全性设计和优化处理等。,2023/6/1,18,7.制定测试计划,在软件开发的早期阶段提前考虑软件的测试计划是很有必要的。这样能促使软件设计人员在设计时注意到软件的测试问题,从而有利于提高软件的可测试性。,2023/6/1,19,8.书写文档,应该用正式的文档记录总体设计的结果,在这个阶段应该完成的文档有以下几种:系统说明,即总体设计说明书。主要
9、包括:系统流程图,系统的物理清单,成本/效益分析;对最佳方案的概括描述,精化的数据流图,用层次图或结构图描绘的数据结构,用IPO图或其他工具简要描述的模块算法,模块间的接口关系,需求、功能和模块三者之间的交叉参照关系。其中最重要的是系统实现方案和软件模块结构。用户手册。根据总体设计阶段的结果,编写的初步的用户操作手册。测试计划。包括测试策略、测试方案、预测的测试结果、测试进度计划等。详细的实现计划数据库设计,2023/6/1,20,9.审查和复查,最后应该对总体设计的结果进行严格的技术审查在技术审查通过之后再由使用部门的负责人从管理角度进行复审。,2023/6/1,21,主要内容,概述设计过程
10、设计原理启发规则描述软件结构的图形工具面向数据流的设计方法,2023/6/1,22,“设计原理”主要内容,模块化抽象逐步求精信息隐藏和局部化模块独立,2023/6/1,23,模块与模块化,模块是由边界元素限定的相邻程序元素(例如,数据说明,可执行的语句)的序列,而且有一个总体标识符代表它。传统方法学中的模块是能够单独命名并独立地完成一定功能的程序语句的集合。例如高级语言中的过程、函数、子程序和宏等都可作为模块。面向对象方法学中的对象是模块,对象内的方法(或称为服务)也是模块。模块是构成程序的基本构件。模块化就是把程序划分成独立命名且可独立访问的模块,每个模块完成一个子功能,把这些模块集成起来构
11、成一个整体,可以完成指定的功能,满足用户的需求。,2023/6/1,24,模块化的依据,依据设函数C(x)定义问题x的复杂程度,E(x)确定解决问题x需要的工作量(时间)。对于两个问题P1和P2:如果C(P1)C(P2),则 E(P1)E(P2)另外还有:C(P1+P2)C(P1)+C(P2)并且可得:E(P1+P2)E(P1)+E(P2)上述不等式表明:单独解决问题P1和P2所需的工作量之和,比把P1和P2合起来作为一个问题来解决时所需的工作量要少。这种“分而治之”的思想提供了模块化的根据:把复杂的问题分解成许多容易解决的小问题,原来的问题也就容易解决了。,2023/6/1,25,合适的模块
12、数目,模块化粒度越小,开发模块的工作量就越小;但模块数目增加,设计模块间接口所需要的工作量将增加。每个系统都相应地有一个最适当的模块数目M,使得系统的开发成本最小。,虽然M不能精确定义,但总成本曲线可以作为分析与设计的指南。如图说明了模块数目和软件成本之间的关系,2023/6/1,26,模块化的优点,软件模块化的优点采用模块化原理可以使软件结构清晰,不仅容易设计也容易阅读和理解。因为程序错误通常局限在有关的模块及它们之间的接口中,所以模块化使软件容易测试和调试,因而有助于提高软件的可靠性。因为变动往往只涉及少数几个模块,所以模块化能够提高软件的可修改性。有助于软件工程的组织管理。模块化是软件的
13、一个重要属性。模块化的特性提供了人们处理复杂的问题的一种方法,同时也使得软件能够被有效地管理。,2023/6/1,27,“设计原理”主要内容,模块化抽象逐步求精信息隐藏和局部化模块独立,2023/6/1,28,抽象的含义,现实世界中一定事物、状态或过程之间总存在着某些相似的方面,即共性。把这些共性集中和概括起来,忽略它们之间的差异,这就是抽象。抽象即抽出事物的本质特性而暂时不考虑它们的细节。它是人类在认识复杂现象的过程中使用的最强有力的思维工具。,2023/6/1,29,抽象的有效方法,抽象的有效方法是用层次的方式构造和分析它。抽象的高层次使用问题环境的语言,以概括的方式叙述问题的解法;在较低
14、层次采用更过程化的方法,把面向问题的术语和面向实现的术语结合起来叙述问题的解法;最后,在最低层次用可直接实现的方式叙述问题的解法。软件工程过程的每一步,都是对软件解法的抽象层次的一次细化。在可行性研究阶段,软件被看作是一个完整的系统部分;在需求分析期间,我们使用在问题环境中熟悉的术语来描述软件的解法;当我们由总体设计阶段转入详细设计阶段时,抽象的程度进一步减少;最后,当源程序写出来时,也就达到了抽象的最低层。,2023/6/1,30,开发一个CAD软件的三层抽象,抽象层次.用问题所处环境的术语来描述这个软件:,该软件包括一个计算机绘图界面,向绘图员显示图形,以及一个数字化仪界面,用以代替绘图板
15、和丁字尺。所有直线、折线、矩形、圆及曲线的描画、所有的几何计算、所有的剖面图和辅助视图都可以用这个CAD软件实现。,2023/6/1,31,抽象层次.任务需求的描述:在这个抽象层次上,未给出“怎样做”的信息,不能直接实现。,开发一个CAD软件的三层抽象,CAD SOFTWARE TASKS user interaction task;2-D drawing creation task;graphics display task;drawing file management task;end.,2023/6/1,32,抽象层次.程序过程表示2-D 绘图生成任务:,开发一个CAD软件的三层抽象,
16、PROCEDURE:2-D drawing creation REPEAT UNTIL(drawing creation task terminates)DO WHILE(digitizer interaction occurs)digitizer interface task;DETERMINE drawing request CASE;line:line drawing task;rectangle:rectangle drawing task;circle:circle drawing task;END DO WHILE(keyboard interaction occurs)keybo
17、ard interaction task;PROCESS analysis/computation CASE view:auxiliary view task;section:cross sectioning task;END;END REPEATEND PROCEDURE,2023/6/1,33,数据抽象的例子,在不同层次上描述数据对象的细节,定义与该数据对象相关的操作。例如,在CAD软件中,定义一个叫做drawing的数据对象。可将drawing规定为一个抽象数据类型,定义它的内部细节为:数据抽象drawing本身由另外一些数据抽象,如geometry、BOM(bill of materi
18、als)构成定义drawing的抽象数据类型之后,可引用它来定义其它数据对象,而不必涉及drawing的内部细节,如定义:blue-print IS INSTANCE OF drawing;或schematic IS INSTANCE OF drawing;,TYPE drawing IS STRUCTURE DEFIND number IS STRING LENGTH(12);geometry DEFIND notes IS STRING LENGTH(256);BOM DEFIND END drawing TYPE;,2023/6/1,34,抽象的意义,我们在考虑问题时,集中考虑和当前问题
19、有关的方面,而忽略和当前问题无关的方面,这就是抽象。或者说抽象就是抽出事物的本质特性而暂时不考虑它们的细节。逐步求精和模块化的概念,与抽象紧密相关。随着软件开发的进展,软件结构每一层中的模块,表示了对软件抽象层次的一次精化。软件结构顶层的模块,控制了系统的主要功能并且影响全局;软件结构底层的模块,完成对数据的一个具体处理。用自顶向下由抽象到具体的方式分配控制,简化了软件的设计和实现,提高了软件的可理解性和可测试性,并且使软件更容易维护。,2023/6/1,35,“设计原理”主要内容,模块化抽象逐步求精信息隐藏和局部化模块独立,2023/6/1,36,逐步求精的含义,逐步求精是人类解决复杂问题时
20、采用的基本方法,也是许多软件工程技术(如规格说明技术,设计和实现技术)的基础。所谓逐步求精即为了能集中精力解决主要问题而尽量推迟对问题细节的考虑。,2023/6/1,37,逐步求精的重要性,逐步求精之所以如此重要,是因为人类的认知过程遵守Miller法则:一个人在任何时候都只能把注意力集中在(72)个知识块上。软件工程师在一段时间内需要考虑的知识块远远多于7,逐步求精能帮助软件工程师将精力集中在与当前开发阶段最相关的那些方面,而忽略对整体解决方案来说虽说是必要的,然而目前还不需要考虑的细节。可以把逐步求精看作是一项把一个时期内必须解决的种种问题按优先级排序的技术。逐步求精方法确保每个问题都将被
21、解决,而且每个问题都将在适当的时候被解决。,2023/6/1,38,逐步求精是一种自顶向下的设计策略,逐步求精是由Niklaus Wirth提出的一种自顶向下的设计策略。按照这种设计策略,程序的体系结构是通过逐步精化处理过程的层次而设计出来的。通过逐步分解对功能的宏观陈述而开发出层次结构,直至最终得出用程序设计语言表达的程序。,2023/6/1,39,Wirth对逐步求精策略的概括说明,我们对付复杂 问题的最重要的办法是抽象:对一个复杂问题不应该立刻用计算机指令、数字和逻辑符号来表示,而应该用较自然的抽象语句来表示,从而得出抽象程序;抽象程序对抽象数据进行某些特定的运算并用某些合适的记号(可能
22、是自然语言)来表示;对抽象程序做进一步的分解,并进入下一个抽象层次,这样的精细化过程一直进行下去,直到程序能被计算机接受为止。这时的程序可能是用某种高级语言或机器语言指令书写的。,2023/6/1,40,逐步求精的实质,求精实际上是细化过程。人们从在高抽象级别定义的功能陈述(或信息描述)开始,也就是说,该陈述仅仅概念性地描述了功能或信息,但是并没有提供功能的内部工作情况或信息的内部结构。求精要求设计者细化原始陈述,随着每个后续求精(即细化)步骤的完成而提供越来越多的细节。,2023/6/1,41,抽象与求精,对付复杂问题常用到抽象,求精实际上是细化过程。抽象与求精是一对互补的概念。抽象使得设计
23、者能够说明过程和数据,同时却忽略了低层细节。可以把抽象看作是一种通过忽略多余细节的同时强调有关的细节,从而实现逐步求精的方法。可以把逐步求精看作是一项把一个时期内必须解决的种种问题按优先级排序的技术。求精则帮助设计者在设计过程中逐步揭示出低层细节。抽象与求精都有助于设计者在设计演化过程中创造出完整的设计模型。,2023/6/1,42,“设计原理”主要内容,模块化抽象逐步求精信息隐藏和局部化模块独立,2023/6/1,43,什么是信息隐藏?,应用模块化原理时,会产生一个问题:“为了得到最好的一组模块,应该怎样分解软件呢?”信息隐藏原理:应该这样设计和确定模块,使得一个模块内包含的信息(过程和数据
24、)对于不需要这些信息的模块来说,是不能访问的,或者说是“不可见”的。,2023/6/1,44,信息隐藏的含义,实际上,应该隐藏的不是有关模块的一切信息,而是模块的实现细节,有人认为应称为细节隐藏。隐藏意味着可以通过定义一组独立的模块来实现有效的模块化,这些独立的模块彼此间仅仅交换那些为了完成系统功能而必须交换的信息。,2023/6/1,45,信息隐藏需要局部化,局部化的概念与信息隐藏的概念密切相关。局部化是指把一些关系密切的软件元素物理地放得彼此靠近。在模块中使用局部数据元素是局部化的一个例子。显然,局部化有助于实现信息隐藏。,2023/6/1,46,信息隐藏的优点,如果在测试期间和以后的软件
25、维护期间需要修改软件,那么使用信息隐蔽原理作为模块化系统设计的标准就会带来极大的好处。对于软件的其它部分来说,绝大部分数据和过程都是隐蔽的,这样,在修改期间由于疏忽而引入的错误所造成的影响就可以局限在一个或几个模块内部,不至波及到软件的其他部分。使用信息隐藏原理设计软件模块,有助于减少修改软件时所犯的错误。,2023/6/1,47,“设计原理”主要内容,模块化抽象逐步求精信息隐藏和局部化模块独立,2023/6/1,48,回顾:模块与模块化,模块是由边界元素限定的相邻程序元素的序列,而且有一个总体标识符代表它。软件系统的模块化是指整个软件被划分成若干单独命名和可编址的部分,即模块。这些模块可以被
26、组装起来以满足整个问题的需求。,2023/6/1,49,模块独立的含义,模块独立的概念是模块化、抽象、信息隐藏和局部化概念的直接结果。模块独立性,是指软件系统中每个模块只涉及软件要求的具体的子功能,而和软件系统中其它的模块的接口是简单的例如,若一个模块只具有单一的功能且与其它模块没有太多的联系,则称此模块具有模块独立性。,2023/6/1,50,模块独立的重要性,为什么模块独立是重要的:有效的模块化的软件比较容易开发出来。这是由于能够分割功能而且接口可以简化,当许多人分工合作开发同一软件时,这个优点尤其重要。独立的模块比较容易测试和维护。这是因为相对地,修改设计和程序需要的工作量较小,错误传播
27、范围小,需要扩充功能时能够“插入”模块。总之,模块独立是好设计的关键,而设计又是决定软件质量的关键环节。,2023/6/1,51,模块独立性的度量,一般采用两个准则度量模块独立性。即耦合和内聚:耦合:衡量不同模块彼此间互相依赖(连接)的紧密程度的度量。内聚:是模块功能强度(一个模块内部各个元素彼此结合的紧密程度)的度量。模块独立性比较强的模块应是高内聚低耦合的模块。,2023/6/1,52,耦合的含义,耦合是对一个软件结构内不同模块之间相互关联程度的度量。耦合强弱取决于:模块间接口的复杂程度进入或访问一个模块的点通过接口的数据,2023/6/1,53,应该追求尽可能松散耦合的系统,在软件设计中
28、应该追求尽可能松散耦合的系统:在这样的系统中可以研究、测试或维护任何一个模块,而不需要对系统的其他模块有很多了解。由于模块间联系简单,发生在一处的错误传播到整个系统的可能性就很小。因此,模块间的耦合程度强烈影响系统的可理解性、可测试性、可靠性和可维护性。,2023/6/1,54,耦合程度自低到高-1,没有耦合。如果任两个模块中的每一个都能独立工作而不需要另一个模块,那么它们彼此完全独立,这意味着模块间无任何连接,即没有耦合。这种耦合的耦合程度最低。一个软件系统中不可能所有模块之间都没有任何连接。在一些教材中,这种情况就“非直接耦合”。,2023/6/1,55,非直接耦合的图例,非直接耦合(No
29、ndirect Coupling)两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的。非直接耦合的模块独立性最强。,2023/6/1,56,耦合程度自低到高-2,数据耦合:如果两个模块彼此间通过参数交换信息,而且交换的信息仅仅是数据,这就是数据耦合。数据耦合是低耦合,系统中至少存在这种耦合。因为只有当某些模块的输出数据作为另一些模块的输入数据时,系统才能完成有价值的功能。一般说来,一个系统内可以只包含数据耦合。,2023/6/1,57,耦合程度自低到高-3,控制耦合:如果两个模块彼此间通过参数交换信息,传递的信息中有控制信息(尽管有时这种控制信息以数据的形式出现),则
30、这种耦合称为控制耦合。控制耦合是中等程度耦合,它增加了系统的复杂程序。它往往是多余的,因为把模块适当分解后通常可用数据耦合代替它。,2023/6/1,58,控制耦合的图例,控制耦合(Control Coupling)如果一个模块通过传送开关、标志、名字等控制信息,明显地控制选择另一模块的功能,就是控制耦合。,2023/6/1,59,耦合程度自低到高-4,特征耦合:如果被调用的模块需要使用作为参数传递进来的数据结构中的所有元素,那么,把整个数据结构作为参数传递就是完全正确的。当把整个数据结构作为参数传递而被调用模块只使用其中一部分数据元素时,就出现特征耦合。在这种情况下,被调用的模块可以使用的数
31、据多于它确实需要的数据,这将导致对数据的访问失去控制,从而为非授权使用数据提供机会。,2023/6/1,60,耦合程度自低到高-5,公共环境耦合:当两个或多个模块通过公共数据环境相互作用时,它们之间的耦合称为公共环境耦合。公共环境可以是全程变量、共享的通信区、内存的公共覆盖区、任何存储介质上的文件、物理设备等。公共环境耦合的复杂程序随耦合的模块个数而变化,当耦合的模块个数增加时复杂程度增加。如果只有两个模块有公共环境:一个模块往公共环境送数据,另一个模块从公共环境取数据。这是比较松散的形式。两个模块都既往公共环境送数据又从里面取数据,这种耦合比较紧密,介于数据耦合和控制耦合之间。如果两个模块共
32、享的数据很多,都通过参数传递可能很不方便,可以利用公共环境耦合。,2023/6/1,61,公共耦合的图例,在一些教材中,公共环境耦合也被称为公共耦合。,2023/6/1,62,耦合程度自低到高-6,内容耦合:两个模块间出现下列4种情况之一,即是内容耦合:一个模块访问另一模块的内部数据;一个模块不通过正常入口转入另一模块;两个模块有一部分程序重叠这只可能出现在汇编语言中;一个模块有多个入口意味着一个模块有几种功能。内容耦合是最高程度的耦合,应该坚决避免。事实上许多高级程序设计语言已经设计成不允许在程序中出现任何形式的内容耦合。,2023/6/1,63,内容耦合的图例,2023/6/1,64,有关
33、耦合的设计原则,耦合是影响软件复杂程度的一个重要因素,应该采取下述设计原则:尽量使用数据耦合少用控制耦合和特征耦合限制公共环境耦合的范围完全不用内容耦合,2023/6/1,65,内聚的含义,内聚:标志一个模块内各个元素彼此结合的紧密程度,它是信息隐藏和局部化概念的自然扩展。简单地说,理想内聚的模块只做一件事情。设计时应该力求做到高内聚,通常中等程度的内聚也是可以采用的,而且效果和高内聚相差不多。,2023/6/1,66,内聚和耦合,内聚和耦合的概念是Constantine、Yourdon、Myers和Stevens等人提出的。内聚和耦合是密切相关的,模块内的高内聚往往意味着模块间的松耦合。内聚
34、和耦合都是进行模块化设计的有力工具。实践表明,应该把更多注意力集中到提高模块的内聚程度上。,2023/6/1,67,内聚的种类,内聚程度自高到低:功能内聚:10分,模块内所有处理元素属于一个整体,完成单一功能。顺序内聚:9分,模块内的处理元素和同一个功能密切相关,并且这些处理必须顺序执行。通信内聚:7分,模块中所有元素都使用同一个输入数据和(或)产生同一个输出数据。过程内聚:5分,模块中处理元素是相关的,而且必须以特定次序执行。时间内聚:3分,一个模块包含的任务必须在同一段时间内执行。逻辑内聚:1分,一个模块完成的任务在逻辑上属于相同或相似的一类。偶然内聚:0分,一个模块完成一组任务,这些任务
35、彼此间即使有关系,也是很松散的。,2023/6/1,68,功能内聚(Functional Cohesion):一个模块中各个部分都是完成某一具体功能必不可少的组成部分,或者说该模块中所有部分都是为了完成一项具体功能而协同工作,紧密联系,不可分割的。则称该模块为功能内聚模块。功能内聚是最高程度的内聚。,内聚种类-1,2023/6/1,69,顺序内聚:如果一个模块内的处理元素和同一个功能密切相关,而且这些处理必须顺序执行(通常一个处理元素的输出数据作为下一个处理元素的输入数据)。根据数据流图划分模块时,通常得到顺序内聚的模块,这种模块彼此间的连接往往比较简单。,顺序内聚和功能内聚都属于高内聚。,内
36、聚种类-2,2023/6/1,70,内聚种类-3,如果一个模块内各功能部分都使用了相同的输入数据,和(或)产生了相同的输出数据,则称之为通信内聚模块。通常,通信内聚模块是通过数据流图来定义的。,通信内聚(Communication Cohesion),2023/6/1,71,过程内聚(Procedural Cohesion):一个模块内的处理元素是相关的,而且必须以特定次序执行。使用流程图做为工具设计程序时,常常通过研究流程图确定模块的划分,把流程图中的某一部分划出组成模块,就得到过程内聚模块。例如,把流程图中的循环部分、判定部分、计算部分分成三个模块,这三个模块都是过程内聚模块。过程内聚与前
37、面的通信内容都属中内聚。,内聚种类-4,2023/6/1,72,时间内聚(Classical Cohesion)时间内聚又称为经典内聚。这种模块大多为多功能模块,但模块的各个功能的执行与时间有关,通常要求所有功能必须在同一时间段内执行。例如初始化模块和终止模块。,内聚种类-5,2023/6/1,73,逻辑内聚(Logical Cohesion):一个模块完成的任务在逻辑上属于相同或相似的一类。如一个模块产生各种类型的全部输出。这种模块把几种相关的功能组合 在一起,每次被调用时,由传送 给模块的判定参数来确定该模块 应执行哪一种功能。,内聚种类-6,2023/6/1,74,偶然内聚(Coinci
38、dental Cohesion):当模块内各部分之间没有联系,或者即使有联系,这种联系也很松散,则称这种模块为巧合内 聚。它是内聚程度最低的模块。,内聚种类-7,2023/6/1,75,偶然内聚、逻辑内聚和时间内聚,偶然内聚、逻辑内聚和时间内聚都属于低内聚。偶然内聚模块中,各种元素之间没有实质性联系,很可能在一种场合需要修改这个模块,而在另一种应用场合又不允许这种修改,从而陷入困境。偶然内聚模块出现修改错误的概率比其他类型的模块高得多。逻辑内聚模块中,不同功能混在一起,合用部分程序代码,即使局部功能的修改有时也会影响全局。逻辑内聚模块的修改也比较。时间关系在一定程度上反映了程序的某些实质,所以
39、时间内聚比逻辑内聚好一些。,2023/6/1,76,程序设计时对内聚的把握,没有必要精确确定内聚的级别。重要的是:设计时力争做到高内聚能够辩认出低内聚的模块有能力通过修改设计:提高模块的内聚程度,降低模块间的耦合程度获得较高的模块独立性,2023/6/1,77,主要内容,概述设计过程设计原理启发规则描述软件结构的图形工具面向数据流的设计方法,2023/6/1,78,什么是启发式规则,所谓启发式规则就是从人们在开发计算机软件的长期实践中积累的丰富经验总结得出的,在许多场合能给软件工程师以有益的启示。启发式规则可以帮助软件工程师找到改进软件设计提高软件质量的途径。,2023/6/1,79,共有7条
40、启发式规则,改进软件结构提高模块独立性模块规模应该适中深度、宽度、扇入和扇出都应适当模块的作用域应该在控制域之内力争降低模块接口的复杂程度设计单入口单出口的模块模块功能应该可以预测,2023/6/1,80,启发式规则之一改进软件结构提高模块独立性,设计出软件的初步结构以后,应该审查分析软件结构,通过模块分解或合并,力求降低耦合提高内聚。例如:多个模块公有的一个子功能可以独立成一个模块,由这些模块调用;有时可以通过分解或合并模块以减少控制信息的传递及对全程数据的引用,并且降低接口的复杂程度。,2023/6/1,81,启发式规则之二模块规模应该适中,经验表明,一个模块的规模不应过大:最好能写在一页
41、纸内,通常不超过60行语句。从心理学的角度研究得知,当一个模块包含的语句数超过30以后,模块的可理解程度迅速下降。过大的模块往往分解不充分,但进一步分解必须符合问题结构,即分解不应降低模块的独立性;过小模块开销大于有效操作,数目过多导致接口复杂。过小的模块有时不值得单独存在,特别是只有一个模块调用它时,通常可以把它合并到上级模块中去而不必单独存在。,启发式规则之三深度、宽度、扇出和扇入都应适当,深度表示软件结构中控制的层数,可粗略标志一个系统的大小和复杂程度。宽度是软件结构内一个层次上的模块总数。一般说,宽度越大系统越复杂。扇出是一个模块直接控制(调用)的模块数目。经验表明,一个设计好的典型系
42、统平均扇出通常是3或4(扇出的上限通常是59)。一个模块的扇入表明有多少个上级模块调用它,扇入越大则共享该模块的上级模块数目越多。,观察大量软件系统后发现,设计得很好的软件结构通常顶层扇出比较高,中层扇出较少,底层扇入到公共的实用模块中去(底层模块有高扇入)。,2023/6/1,83,启发式规则之四模块的作用域应在控制域内,模块的作用域是受该模块内一个判定影响的所有模块的集合。模块的控制域是这个模块本身以及所有直接或间接从属于它的模块的集合。如A的控制域是A、B、C、D、E、F。,所有受判定影响的模块应该都从属于做出判定的那个模块,最好局限于做出判定的模块本身及它直属的下级模块。例如:模块A做
43、出的判定只影响模块B;如果其判定也影响到G,则A、G间出现控制耦合。,2023/6/1,84,如何使作用域在控制域内,怎样修改软件结构才能使模块的作用域是其控制域的子集?一个方法是:尽量把做判定的点往上移,例如,把判定从模块A中移到模块M中。另一个方法是把那些在作用域内但不在控制域内的模块移到控制域内。例如,把模块G移到模块A的下面,成为它的直属下级模块。到底采用哪种方法改进软件结构,需要根据具体问题统筹考虑:一方面要考虑哪种方法更现实;一方面应该使软件结构能最好地又要体现问题原来的结构。,2023/6/1,85,启发式规则-5力争降低模块接口的复杂程度,模块接口复杂是软件发生错误的一个主要原
44、因。应使信息传递简单并且和模块的功能一致。如求一元二次方程的根:模块QUAD_ROOT(TBL,X),其中用数组TBL传送方程的系数,用数组回送求得的根。这种传递信息的方法不利于对这个模块的理解。模块QUAD_ROOT(A,B,C,ROOT1,ROOT2),其中A、B、C是方程系数,ROOT1、ROOT2是求得的根。这种传递信息的方法较好。接口复杂或不一致(即看起来传递的数据之间没有联系),是紧耦合或低内聚的征兆,应该重新分析这个模块的独立性。,2023/6/1,86,启发式规则-6设计单入口单出口的模块,即不要使模块间出现内容耦合。从顶部进入模块且从底部退出时,软件是比较容易理解的,因此也是
45、比较容易维护的。,2023/6/1,87,启发式规则-7模块功能应该可以预测,模块功能应该可以预测,但也要防止模块功能过分局限。如果一个模块可以当做黑盒子(同样的输入就会产生同样的输出),就是可以功能预测的。带有内部“存储器”的模块功能可能是不可预测的,因为它的输出可能取决于内部存储器(例如某个标记)的状态。由于内部存储器对于上级模块而言是不可见的,所以这样的模块既不易理解又难于测试和维护。,2023/6/1,88,模块功能要防止过分局限,如果一个模块只完成一个单独的子功能,则呈现高内聚。但是,如果一个模块任意限制局部数据结构的大小,过分限制在控制流中可以做出的选择或者外部接口的模式,那么这种
46、模块的功能就过分局限,使用范围也就过分狭窄。在使用过程中将不可避免地需要修改功能过分局限的模块,以提高模块的灵活性,扩大它的使用范围。,2023/6/1,89,启发式规则的作用,上面共有7条启发式规则,它们多是经验规律:对改进设计,提高软件质量,往往有重要的参考价值;但既不是设计的目标也不是设计时应普遍遵循的原理。,2023/6/1,90,主要内容,概述设计过程设计原理启发规则描述软件结构的图形工具面向数据流的设计方法,2023/6/1,91,“描述软件结构的图形工具”内容,层次图和HIPO图结构图,2023/6/1,92,层次图,层次图用来描述软件的层次结构,适合在自顶向下软件设计过程中使用
47、。层次图中的一个矩形框代表一个模块,方框间的连线表示调用关系而不像层次方框图那样表示组成关系。层次方框图用树形结构的一系列多层次的矩形框描绘数据的层次结构。树形结构的顶层是一个单独的矩形框,它代表完整的数据结构;下面的各层矩形框代表这个数据的子集;最底层的框代表组成这个数据的实际数据元素(不能再分割的元素)。,2023/6/1,93,HIPO图,HIPO图是IBM公司发明的“层次图加输入/处理/输出图”的英文缩写。为了能使HIPO图具有可追踪性,在H图(层次图)里除了最顶层的方框之外,每个方框都加了编号。和H图中每个方框相对应,应该有一张IPO图描绘这个方框代表的模块的处理过程。HIPO图中的
48、每张IPO图内都应该明显地标出它所描绘的模块在H图中的编号,以便追踪了解这个模块在软件结构中的位置。,2023/6/1,94,“描述软件结构的图形工具”内容,层次图和HIPO图结构图,2023/6/1,95,结构图,结构图是由Yourdon提出的。它反映程序中模块之间的层次调用关系和联系:以特定的符号表示模块、模块间的调用关系和模块间信息的传递。结构图和层次图类似,是进行软件结构设计的图形工具。结构图中一个方框代表一个模块,框内注明模块的名字或主要功能;方框之间的箭头(或直线)表示模块的调用关系。因为按照惯例总是图中位于上方的方框代表的模块调用下方的模块,即使不用箭头也不会产生二义性。为了简单
49、起见,可以只用直线而不用箭头表示模块间的调用关系。,2023/6/1,96,结构图模块间传递消息的表示,模块间的信息传递:当一个模块调用另一个模块时,调用模块把数据或控制信息传送给被调用模块,以使被调用模块能够运行。被调用模块在执行过程中又把它产生的数据或控制信息回送给调用模块。,结构图的基本符号,图a表示模块调用的基本形式。用带注释的箭头表示模块调用过程中来回传递的信息:注释箭头尾部是空心圆表示传递的是数据实心圆表示传递的是控制信息图b表示模块的顺序调用。模块A顺序调用模块B、C和D。图c表示模块的选择调用。当模块A中某个判定为真时调用模块B,为假时调用模块C。图d表示模块的循环调用。模块A
50、循环调用模块B。,2023/6/1,98,产生最佳解的结构图,带注释的箭头表示模块调用过程中来回传递的信息。利用注释箭头尾部的形状来区分传递的信息是数据还是控制信息:尾部是空心圆表示传递的是数据,实心圆表示传递的是控制信息。,2023/6/1,99,层次图、结构图的欠缺,层次图和结构图不严格表示模块的调用次序,虽然多数人习惯于按调用次序从左到右画模块,但并没有这种规定。层次图和结构图不指明什么时候调用下层模块。通常上层模块中除了调用下层模块外还有其他语句,究竟先执行调用下层模块的语句还是先执行其他语句,在图中没有指明。层次图和结构图只表明一个模块调用那些模块,没有表明模块内还有没有其他成分。通