您好,欢迎访问三七文档
当前位置:首页 > 建筑/环境 > 工程监理 > 软件工程VER2第4章-张海藩
湘潭大学第4章结构化设计•传统的软件工程方法学采用结构化设计(StructuredDesign,SD)技术,完成软件设计工作,通常把软件设计工作划分为概要设计和详细设计这样两个阶段。•概要设计的主要任务是,通过仔细分析软件规格说明,适当地对软件进行功能分解,从而把软件划分为模块,并且设计出完成预定功能的模块结构。•详细设计阶段详细地设计每个模块,确定完成每个模块功能所需要的算法和数据结构。4.1结构化设计与结构化分析的关系•软件设计必须依据对软件的需求来进行,结构化分析的结果为结构化设计提供了最基本的输入信息。•分析模型的每个元素都提供了创建设计模型时所需要的信息。图4.1描绘了软件设计过程中的信息流。•由数据模型、功能模型和行为模型清楚地表示的软件需求被传送给软件设计者,他们使用适当的设计方法完成数据设计、体系结构设计、接口设计和过程设计。图4.1把分析模型转变成软件•在软件设计期间我们所做出的决策,将最终决定软件开发能否成功,更重要的是,这些设计决策将决定软件维护的难易程度。4.2软件设计的概念和原理•模块化•模块是由边界元素限定的相邻的程序元素(例如,数据说明,可执行的语句)的序列,而且有一个总体标识符来代表它。像Pascal或Ada这样的块结构语言中的Begin…end对,或者C,C++和Java语言中的{…}对,都是边界元素的例子。因此,过程、函数、子程序和宏等,都可作为模块。面向对象范型中的对象是模块,对象内的方法也是模块。模块是构成程序的基本构件。模块化•模块化就是把程序划分成独立命名且可独立访问的模块,每个模块完成一个子功能,把这些模块集成起来构成一个整体,可以完成指定的功能满足用户的需求。•模块化是为了使一个复杂的大型程序能被人的智力所管理,软件应该具备的惟一属性。是人类解决问题一般规律在软件设计中的具体应用。(分解问题,各个击破)模块化图4.2模块化和软件成本模块化•Meyer提出了五条标准,可以用这五条标准来评价一种设计方法定义有效的模块系统的能力。这五条标准是:(1)模块可分解性;(2)模块可组装性;(3)模块可理解性;(4)模块连续性;(5)模块保护性。模块化(1)模块可分解性•如果一种设计方法提供了把问题分解为子问题的系统化机制,它就能降低整个问题的复杂性,从而可以实现一种有效的模块化解决方案。(2)模块可组装性•如果一种设计方法能把现有的(可重用的)设计构件组装成新系统,它就能提供一种并非一切都从头开始做的模块化解决方案。模块化(3)模块可理解性•如果可以把一个模块作为一种独立单元(无需参考其他模块)来理解,那么,这样的模块是易于构造和易于修改的。(4)模块连续性•如果对系统需求的微小修改只导致对个别模块,而不是对整个系统的修改,则修改所引起的副作用将最小。(5)模块保护性•如果在一个模块内出现异常情况时,它的影响局限在该模块内部,则由错误引起的副作用将最小。模块化的优点•采用模块化原理可以使软件结构清晰,不仅容易设计也容易阅读和理解。•因为程序错误通常局限在有关的模块及它们之间的接口中,所以模块化使软件容易测试和调试,因而有助于提高软件的可靠性。•因为变动往往只涉及少数几个模块,所以模块化能够提高软件的可修改性。•模块化也有助于软件开发工程的组织管理,一个复杂的大型程序可以由许多程序员分工编写不同的模块,并且可以进一步分配技术熟练的程序员编写困难的模块。抽象•人类在认识复杂现象的过程中使用的最强有力的思维工具是抽象。人们在实践中认识到,在现实世界中一定事物、状态或过程之间总存在着某些相似的方面(共性)。把这些相似的方面集中和概括起来,暂时忽略它们之间的差异,这就是抽象。或者说抽象就是抽出事物的本质特性而暂时不考虑它们的细节。•软件工程过程的每一步都是对软件解法的抽象层次的一次精化。逐步求精•逐步求精是人类解决复杂问题时采用的基本技术,也是许多软件工程技术(例如,规格说明技术,设计和实现技术、测试和集成技术)的基础。可以把逐步求精定义为:“为了能集中精力解决主要问题而尽量推迟对问题细节的考虑。”•求精实际上是细化过程。我们从在高抽象级别定义的功能陈述(或信息描述)开始。也就是说,该陈述仅仅概念性地描述了功能或信息,但是并没有提供功能的内部工作情况或信息的内部结构。求精要求设计者细化原始陈述,随着每个后续求精(细化)步骤的完成而提供越来越多的细节。逐步求精•抽象与求精是一对互补的概念。抽象使得设计者能够说明过程和数据,同时却忽略低层细节。事实上,可以把抽象看作是一种通过忽略多余的细节同时强调有关的细节,而实现逐步求精的方法。•求精则帮助设计者在设计过程中揭示出低层细节。这两个概念都有助于设计者在设计演化过程中创造出完整的设计模型。信息隐藏•应用模块化原理时,自然会产生的一个问题是:“为了得到最好的一组模块,应该怎样分解软件”。•信息隐藏原理指出:应该这样设计和确定模块,使得一个模块内包含的信息(过程和数据)对于不需要这些信息的模块来说,是不能访问的。•信息隐藏是隐藏模块的实现细节。•“隐藏”意味着有效的模块化可以通过定义一组独立的模块来实现。这组模块之间只交换那些必须交换的信息。4.3模块独立•“模块独立”概念是模块化、抽象、逐步求精和信息隐藏等概念的直接结果,也是完成有效的模块设计的基本标准。•模块的独立程度可以由两个定性标准来度量,这两个标准分别称为内聚和耦合。耦合衡量不同模块彼此间互相依赖(连接)的紧密程度;内聚衡量一个模块内部各个元素彼此结合的紧密程度。耦合•耦合是对一个软件结构内不同模块之间互连程度的度量。耦合强弱取决于模块间接口的复杂程度,进入或访问一个模块的点,以及通过接口的数据。•在软件设计中应该追求尽可能松散耦合的系统。在这样的系统中可以研究、测试或维护任何一个模块,而不需要对系统的其他模块有很多了解。此外,由于模块间联系简单,发生在一处的错误传播到整个系统的可能性就很小。因此,模块间的耦合程度强烈影响系统的可理解性、可测试性、可靠性和可维护性。耦合•数据耦合:如果一个模块访问另一个模块时,彼此之间是通过数据参数(不是控制参数、公共数据结构或外部变量)来交换输入、输出信息的,则称这种耦合为数据耦合。数据耦合是松散的耦合,模块之间的独立性比较强。•控制耦合:如果一个模块通过传送开关、标志、名字等控制信息,明显地控制选择另一模块的功能,就是控制耦合。•特征耦合:如果把整个数据结构作为参数传递而被调用的模块只需要使用一部分数据元素时,就出现了特征耦合。耦合•公共环境耦合:若一组模块都访问同一个公共数据环境,则它们之间的耦合就称为公共耦合。公共的数据环境可以是全局数据结构、共享的通信区、内存的公共覆盖区等。•内容耦合:如果一个模块直接访问另一个模块的内部数据;或者一个模块不通过正常入口转到另一模块内部;或者两个模块有一部分程序代码重迭;或者一个模块有多个入口,则两个模块之间就发生了内容耦合。耦合•总之,耦合是影响软件复杂程度的一个重要因素。应该采取下述设计原则:•尽量使用数据耦合,少用控制耦合,限制公共环境耦合的范围,完全不用内容耦合。内聚•内聚标志一个模块内各个元素彼此结合的紧密程度,它是信息隐蔽和局部化概念的自然扩展。简单地说,理想内聚的模块只做一件事情。•设计时应该力求做到高内聚,通常中等程度的内聚也是可以采用的,而且效果和高内聚相差不多;但是,低内聚很坏,不要使用。内聚•巧合内聚(偶然内聚):当几个模块内凑巧有一些程序段代码相同,又没有明确表现出独立的功能,把这些代码独立出来建立的模块即为巧合内聚模块。它是内聚程度最低的模块。缺点是模块的内容不易理解,不易修改和维护。•逻辑内聚:这种模块把几种相关的功能组合在一起,每次被调用时,由传送给模块的控制型参数来确定该模块应执行哪一种功能。逻辑内聚模块比巧合内聚模块的内聚程度要高。因为它表明了各部分之间在功能上的相关关系。内聚•时间内聚(经典内聚):这种模块大多为多功能模块,但要求模块的各个功能必须在同一时间段内执行。例如初始化模块和终止模块。时间内聚模块比逻辑内聚模块的内聚程度又稍高一些。在一般情形下,各部分可以以任意的顺序执行,所以它的内部逻辑更简单。•过程内聚:使用程序流程图做为工具设计程序的时侯,常常通过流程图来确定模块划分。把流程图中的某一部分划出组成模块,就得到过程内聚模块。这类模块的内聚程度比时间内聚模块的内聚程度更强一些。内聚•通信内聚:如果一个模块内各功能部分都使用了相同的输入数据,或产生了相同的输出数据,则称之为通信内聚模块。通常,通信内聚模块是通过数据流图来定义的。•顺序内聚:这种模块内部的处理元素和同一个功能密切相关,而且这些处理必须顺序执行。根据数据流图划分时,通常得到这类模块。•功能内聚:一个模块中所有处理元素属于一个整体,完成一个单一功能。则称该模块为功能内聚模块。功能内聚模块是内聚性最强的模块。内聚•内聚和耦合是密切相关的,模块内的高内聚往往意味着模块间的松耦合。内聚和耦合都是进行模块化设计的有力工具,但是实践表明内聚更重要,应该把更多注意力集中到提高模块的内聚程度上。•事实上,没有必要精确确定内聚的级别。重要的是设计时力争做到高内聚,并且能够辨认出低内聚的模块,有能力通过修改设计提高模块的内聚程度降低模块间的耦合程度,从而获得较高的模块独立性。4.4启发规则•软件工程师们在开发计算机软件的长期实践中积累了丰富的经验,总结这些经验得出了一些启发规则。这些启发规则虽然不像前两节讲述的基本原理那样普遍适用,但是在许多场合仍然能给软件工程师有益的启示,往往能帮助他们找到改进软件设计提高软件质量的途径,因此有助于实现有效的模块化。下面介绍几条常用的启发规则。改进软件结构提高模块独立性•设计出软件的初步结构后,应该分析审查这个结构,通过模块分解或合并,力求降低耦合提高内聚。例如,多个模块公有的一个子功能可以独立成一个模块,由这些模块调用;有时可通过分解或合并模块以减少控制信息的传递以及对全程数据的引用,并且降低接口的复杂程度。模块规模应该适中•经验表明,一个模块的规模不应过大,通常不超过60行语句,能写在一页纸内。从心理学研究得知,当一个模块包含的语句数超过30以后,模块的可理解程度迅速降低。•过大的模块是由于分解不充分,但进一步分解必须符合问题结构,一般而言,分解后不应降低模块独立性。•过小的模块开销大于有效操作,模块数目过多使接口复杂。故过小的模块不值得单独存在,特别是只有一个模块调用它时,可以把它合并上级模块中。深度、宽度、扇出和扇入都应适当•深度表示软件结构中控制的层数,往往能粗略地标志一个系统的大小。深度和程序长度之间应有粗略的对应关系,如果层数过多则应考虑是否有许多管理模块过分简单,能否适当合并。•宽度是软件结构内同一层次上的模块总数的最大值。一般地,宽度越大系统越复杂。对宽度影响最大的因素是模块的扇出。•模块的扇入和扇出:扇出表示一个模块直接调用(或控制)的其它模块数目。扇入则定义为调用(或控制)一个给定模块的模块个数。多扇出意味着需要控制和协调许多下属模块。而多扇入的模块通常是公用模块。•扇出过大意味着模块过分复杂,需要控制和协调过多的下级模块;扇出过小也不好。扇出的上限通常是5~9。设计得好的典型系统的平均扇出通常是3或4。深度、宽度、扇出和扇入都应适当•扇出太大一般是因为缺乏中间层次,应适当增加中间层次的控制模块。扇出太小时可以把下级模块进一步分解成若干个子功能模块,或者合并到它的上级模块中去。但合并或分解必须符合问题结构,不能违背模块独立原理。•多扇入的模块通常是公用模块,扇入越大则共享该模块的上级模块越多,这有好处,但不能违背模块独立原理单纯追求高扇入。•设计得很好的软件结构通常顶层扇出比较高,中层扇出比较少,底层模块有高扇入。模块的作用域应该在控制域之内•模块的作用域:受该模块内一个判定影响的所有模块的集合。•模块的控制域:这个模块本身以及所有直接或间接从属于它的模块的集合。•规则:•一个设计得很好的系统中,所有受判定影响的模块应该都从属于做出判定的那个模块,最好局限于做出判
本文标题:软件工程VER2第4章-张海藩
链接地址:https://www.777doc.com/doc-1371812 .html