《软件结构设计》PPT课件.ppt
第4章 软件结构设计,设计:应用各种技术和原理,对设备、过程或系统作出足够详细的定义,使之能够在物理上得以实现。软件结构设计:是一个把软件需求变换为软件表示的过程,是对软件的整体结构、程序结构、数据结构、文件结构、接口定义等的设计,是宏观上的设计。,4.1 软件结构设计概述,软件设计与程序设计的区别:,程序设计就是编程序,这是大家熟悉的,很多人印象中的“做软件”就是编程序,因此可能有人会把程序设计和软件设计等同起来。这是不对的,软件设计是宏观上的设计。而程序设计仅仅是软件设计的实现,所以做软件决不简单等同与编程序。,4.2 软件结构设计的目标、任务和过程,目标:综合采用各种技术手段,将系统需求转换为数据结构、模块结构(或对象/类结构)的表达形式,并实现系统的性能、安全性、可靠性要求。取得最佳方案。最佳方案的标准:(1)开发费用省;(2)资源消耗低;(3)开发时间短;(4)生产效率高;(5)可靠性较高;(6)可维护性好。,结果:用模块结构图表达。,任务:,结构设计是一个自顶向下,逐步具体的综合性的设计过程。主要内容:,(1)综合分析系统的各种实现方案,提出最佳实现方案的建议。,(2)制定设计规范、标准及约定原则。,(3)软件结构设计:采用某种软件设计方法,按照模块的构造原则,逐步、逐层地设计软件的模块层次结构。,(4)数据结构以及接口的设计。,(5)系统性能设计。,(6)系统安全性能设计:系统的自保护设计;数据一致性设计;容错设计。,(7)系统可靠性设计。,(8)设计文档的编写:结构设计说明书;用户手册;系统初步的测试计划说明书。,(9)设计的审查和复审。,软件结构设计过程:,1.设想供选择方案;2.选择合理的方案;3.推荐最优方案;4.功能分解;5.设计软件结构;6.设计数据库;7.制订测试计划;8.书写文档;9.审查和复审;,4.3 软件设计中的基本概念和原理,1.模块化 所谓模块,是指具有相对独立性的,由数据说明、执行语句等程序对象构成的集合。程序中的每个模块都需要单独命名,通过名字可实现对指定模块的访问。在高级语言中,模块具体表现为函数、子程序、过程等。一个模块具有输入/输出(接口)、功能、内部数据和程序代码四个特征。输入/输出用于实现模块与其他模块间的数据传送,即向模块传入所需的原始数据及从模块传出得到的结果数据。功能指模块所完成的工作。模块的输入/输出和功能构成了模块的外部特征。内部数据是指仅能在模块内部使用的局部量。程序代码用于描述实现模块功能的具体方法和步骤。模块的内部数据和程序代码反映的是模块的内部特征。,模块化是指将整个程序划分为若干个模块,每个模块用于实现一个特定的功能。划分模块对于解决大型复杂的问题是非常必要的,可以大大降低解决问题的难度。为了说明这一点,我们可对问题复杂性、开发工作量和模块数之间的关系进行以下推理。首先,我们设C(x)为问题x所对应的复杂度函数,E(x)为解决问题x所需要的工作量函数。对于两个问题P1和P2,如果:C(P1)C(P2)即问题P1的复杂度比P2高,则显然有:E(P1)E(P2)即解决问题P1比P2所需的工作量大。,在人们解决问题的过程中,发现存在有另一个有趣的规律:C(P1+P2)C(P1)+C(P2)即解决由多个问题复合而成的大问题的复杂度大于单独解决各个问题的复杂度之和。也就是说,对于一个复杂问题,将其分解成多个小问题分别解决比较容易。由此我们可以推出:E(P1+P2)E(P1)+E(P2)即将复杂问题分解成若干个小问题,各个击破,所需要的工作量小于直接解决复杂问题所需的工作量。,根据上面的推理,我们可以得到这样一个结论,模块化可以降低解决问题的复杂度,从而降低软件开发的工作量。虽然增加程序中的模块数可以降低开发每个模块的工作量,但同时却增加了设计模块接口的工作量。通过图4.1所示的模块数与软件开发成本的关系图中可以看出,当划分的模块数处于最小成本区时,开发软件的总成本最低。模块化不但可以降低软件开发的难度,而且可以使程序结构清晰,增加易读性和易修改性。此外,模块化还有利于提高代码的可重用性及团队合作开发大型软件的可行性。,图4.1 模块数与软件开发成本,2.模块独立性 1)耦合性 耦合性是对一个软件结构内部不同模块间联系紧密程度的度量指标。模块间的联系越紧密,耦合性就越高,模块的独立性也就越低。由于模块间的联系是通过模块接口实现的,因此,模块耦合性的高低主要取决于模块接口的复杂程度、调用模块的方式以及通过模块接口的数据。模块间的耦合性主要可划分为如下几种类型。,(1)数据耦合。若两个模块之间仅通过模块参数交换信息,且交换的信息全部为简单数据,则称这种耦合为数据耦合。数据耦合的耦合性最低,通常软件中都包含有数据耦合。数据耦合的例子如下所示:,(2)公共耦合。若两个或多个模块通过引用公共数据相互联系,则称这种耦合为公共耦合。例如,在程序中定义了全局变量,并在多个模块中对全局变量进行了引用,则引用全局变量的多个模块间就具有了公共耦合关系。FORTRAN语言中使用的common语句也会在多个模块间建立公共耦合关系。公共耦合的复杂度随着耦合的模块个数的增加而显著增加。在程序设计中,若两个模块间需要交换的数据较多,仅通过参数传递难以实现时,可以考虑采用公共耦合完成,但一定注意尽量降低公共耦合的程度。,(4)内容耦合。若一个模块对另一模块中的内容(包括数据和程序段)进行了直接的引用甚至修改,或通过非正常入口进入到另一模块内部,或一个模块具有多个入口,或两个模块共享一部分代码,则称模块间的这种耦合为内容耦合。内容耦合是所有耦合关系中程度最高的,会使因模块间的联系过于紧密而对后期的开发和维护工作带来很大的麻烦,因此,应坚决避免任何形式的内容耦合。实际上,许多高级程序设计语言在规定语法时就已经杜绝了任何形式的内容耦合。耦合是影响软件复杂度的一个重要因素,设计过程中应力求降低程序的耦合性。在以上所介绍的耦合中,数据耦合的程度最低,其次是公共耦合,再其次是控制耦合,程度最高的是内容耦合。,2)内聚性 内聚性是对一个模块内部各个组成元素之间相互结合的紧密程度的度量指标。模块中组成元素结合的越紧密,模块的内聚性就越高,模块的独立性也就越高。模块的内聚性和耦合性是两个相互对立且又密切相关的概念。事实上,它们是同一事物的两个方面,模块的高内聚性往往就意味着模块间的低耦合性。因为程序中的各个部分必定是有联系的,若将其中密切相关的部分放在同一个模块中,模块间的联系就会降低;反之,若将密切相关的部分分散放在不同的模块之中,模块间的联系必然会加强。在进行模块化设计时,耦合性和内聚性都是必须考虑的重要指标。但在软件设计时应将更多的注意力集中在提高模块的内聚性上。模块的内聚性主要可划分为如下几种不同的类型。,(1)偶然内聚。若一个模块由多个完成不同任务的语句段组成,各语句段之间的联系十分松散或根本没有任何联系,则称此模块的内聚为偶然内聚。例如,程序中多处出现一些无联系的语句段序列,为了节省内存空间将其组合成为一个模块,这个模块就属于偶然内聚。偶然内聚的模块由于组成部分之间没有实质的联系,因此难于理解和修改,会给软件开发带来很大的困扰。偶然内聚是内聚程度最低的一种,在软件设计时应尽量避免。,(2)逻辑内聚。若一个模块可实现多个逻辑上相同或相似的一类功能,则称该模块的内聚为逻辑内聚。例如,将程序中多种不同类型数据的输出放在同一个模块中实现,这个模块就属于逻辑聚合。逻辑内聚比偶然内聚的内聚程度高一些。虽然逻辑聚合模块的组成部分之间有一定的关系,但不同功能混在一起并公用模块中的部分代码,给修改带来了一定的麻烦。另外,为了在调用模块时能选择执行其中的某个功能,需要传递相应的控制参数,因而会造成模块间的控制耦合,降低模块的独立性。,(3)时间内聚。若一个模块包含了需要在同一时间段中执行的多个任务,则称该模块的内聚为时间内聚。例如,将多个变量的初始化放在同一个模块中实现,或将需要同时使用的多个库文件的打开操作放在同一个模块中,都会产生时间内聚的模块。由于时间内聚模块中的各个部分在时间上的联系,其内聚程度比逻辑内聚高一些。但这样的模块往往会和其他相关模块有着紧密的联系,因而会造成耦合性的增加。,(4)过程内聚。若一个模块中的各个部分相关,并且必须按特定的次序执行,则称该模块的内聚为过程内聚。在结构化程序中,通常采用程序流程图作为设计软件和确定模块划分的工具,因此,这样得到的模块往往具有过程内聚的特性。(5)通信内聚。若一个模块中的各个部分使用同一个输入数据或产生同一个输出数据,则称该模块的内聚为通信内聚。由于通信内聚模块中的各个部分都与某个共同的数据密切相关,因此内聚性高于前几种内聚。,(6)顺序内聚。若一个模块中的各个部分都与同一个功能密切相关,并且必须按照先后顺序执行(通常前一个部分的输出数据就是后一个部分的输入数据),则称该模块的内聚为顺序内聚。例如,在一个处理学生成绩的模块中,前一个部分根据成绩统计出及格的学生人数,后一个部分根据及格人数计算出学生的及格率。根据数据流图划分出的模块通常都是顺序内聚的模块。由于顺序内聚模块中的各个部分在功能和执行顺序上都密切相关,因此内聚程度很高且易于理解。,(7)功能内聚。若一个模块中各个组成部分构成一个整体并共同完成一个单一的功能,则称该模块的内聚为功能内聚。由于功能内聚模块中的各个部分关系非常密切,构成一个不可分割的整体,因此功能内聚是所有内聚中内聚程度最高的一种。在以上所介绍的七种内聚中,按照内聚性从低到高进行排列的结果如图4.2所示。,图4.2 内聚性的排列,3.抽象 抽象是人类在解决复杂问题时经常采用的一种思维方式,它是指将现实世界中具有共性的一类事物的相似的、本质的方面集中概括起来,而暂时忽略它们之间的细节差异。在软件开发中运用抽象的概念,可以将复杂问题的求解过程分层,在不同的抽象层上实现难度的分解。在抽象级别较高的层次上,可以将琐碎的细节的信息暂时隐藏起来,以利于解决系统中的全局性的问题。软件开发过程中从问题定义到最终的软件生成,每一阶段都是在前一阶段基础上对软件解法的抽象层上的一次求精和细化。,结构化程序中自顶向下、逐步求精的模块划分思想正是人类思维中运用抽象方法解决复杂问题的体现。软件结构中顶层的模块抽象级别最高,控制并协调软件的主要功能且影响全局;软件结构中位于底层的模块抽象级别最低,具体实现数据的处理过程。采用自顶向下、由抽象到具体的思维方式,不但降低了软件开发中每个阶段的工作难度,简化了软件的设计和实现过程,还有助于提高软件的可读性、可测试性和可维护性。此外,在程序设计中运用抽象的方法还能够提高代码的可重用性。,4.信息隐蔽 信息隐蔽是指一个模块将自身的内部信息向其他模块隐藏起来,以避免其他模块不恰当的访问和修改,只有对那些为了完成系统功能所必须的数据交换才被允许在模块间进行。信息隐蔽的目的主要是为了提高模块的独立性,减少将一个模块中的错误扩散到其他模块的机会。但信息隐蔽并不意味着某个模块中的内部信息对其他模块来说是完全不可见或不能使用的,而是说模块之间的信息传递只能通过合法的调用接口来实现。显然,信息隐蔽对提高软件的可读性和可维护性都是非常重要的。,5.逐步求精“为了能集中精力解决主要问题而尽量推迟对问题细节的考虑”。可以看作是一项把一个时期内必须解决的种种问题按优先级排列序的技术,是由Niklaus Wirth提出的一种自顶向下的设计策略。求精实际上是一个细化过程。抽象与求精是一对互补的概念。,4.4 启发式规则,(1)降低模块的耦合性,提高模块的内聚性。为了提高软件中各个模块的独立性,提高程序的可读性、可测试性和可维护性,在软件体系结构设计时应尽可能采用内聚性高的模块,如最好实现功能内聚;尽量只使用数据耦合,限制公共耦合的使用,避免控制耦合的使用,杜绝内容耦合的出现。,(2)保持适中的模块规模。程序中模块的规模过大,会降低程序的可读性;而模块规模过小,势必会导致程序中的模块数目过多,增加接口的复杂性。对于模块的适当规模并没有严格的规定,但普遍的观点是模块中的语句数最好保持在10100之间。为了使模块的规模适中,在保证模块独立性的前提下,可对程序中规模过小的模块进行合并或对规模过大的模块进行分解。,(3)模块应具有高扇入和适当的扇出 在模块调用中,某个模块的上级模块数被称为该模块的扇入(如图4.3(a)所示,模块M的扇入数为n);而某个模块可以调用的下级模块数被称为该模块的扇出(如图4.3(b)所示,模块M的扇出数为k)。显然,一个模块的扇入表明了共有多少个模块需要调用该模块,而其扇出表明了该模块可以控制的下级模块的数目。,图4.3 模块的扇入和扇出(a)扇入;(b)扇出,模块的扇入越大,则说明共享该模块的上级模块数越多,或者说该模块在程序中的重用性越高,这正是程序设计所追求的目标之一。当多个模块具有一部分相同功能时,应将这部分相同的功能分离出来,编写成独立的模块供需要的模块调用。通过消除不同模块中的重复内容,提高代码的可重用性,可以减少程序的总代码量,便于程序的测试和维护。,模块的扇出若过大,如在一个模块中要调用八个下级模块,则会使该模块的调用控制过于复杂。这种现象发生的原因通常都是由于设计阶段,模块细化的过程中,分解速度过快造成的。最常见的解决办法是通过在此模块和下级模块间增加一个中间层来控制模块分解的速度。模块的扇出过小,如扇出为1(下级模块层中只有一个模块),在系统设计中通常是不可取的。常见的解决方法是考虑将其合并到上级模块中。但若合并会影响模块的独立性,则将其保留下来也未尝不可。根据实践经验,设计良好的典型系统中,模块的平均扇出通常为3或4。,可以看出:在一个好的软件结构中,模块应具有较高的扇入和适当的扇出。但绝不能为了单纯追求高扇入或合适的扇出而破坏了模块的独立性。此外,经过对大量软件系统的研究后发现,在设计良好的软件结构中,通常顶层的扇出数较大,中间层的扇出数较小,底层的扇入数较大,如图4.4所示。,图4.4 软件结构图示例,(4)软件结构中的深度和宽度不宜过大。所谓深度,是指软件体系结构中控制的层数,它能够粗略地反映出软件系统的规模和复杂程度;所谓宽度,是指软件体系结构内同一层次上模块个数的最大值,通常宽度越大的系统越复杂。如图4.6所示的软件结构图中,深度为5,宽度为8。深度在程序中表现为模块的嵌套调用,嵌套的层数越多,程序就越复杂。模块可以调用的下级模块数越多,软件结构的宽度就越大。深度过大可通过将结构中过于简单的模块分层与上一级模块合并来解决;而宽度过大则可通过增加中间层来解决。显然,软件结构中的深度和宽度是相互对立的两个方面,降低深度会引起宽度的增加,而降低宽度又会带来深度的增加。,(5)模块的作用域应处于其控制域范围之内。模块的作用域是指受该模块内一个判定条件影响的所有模块范围。模块的控制域是指该模块本身以及所有该模块的下属模块(包括该模块可以直接调用的下级模块和可以间接调用的更下层的模块)。例如,在图4.5中,模块C的控制域为模块C、E和F;若在模块C中存在一个对模块D、E和F均有影响的判定条件,即模块C的作用域为模块C、D、E和F(图中带阴影的模块),则显然模块C的作用域超出了其作用域。由于模块D在模块C的作用域中,因此模块C对模块D的控制信息必然要通过上级模块B进行传递,这样不但会增加模块间的耦合性,而且会给模块的维护和修改带来麻烦(若要修改模块C,可能会对不在它控制域中的模块D造成影响)。因此,软件设计时应使各个模块的作用域处于其控制域范围之内。若发现不符合此设计原则的模块,可通过下面的方法进行改进:,将判定位置上移。如将图4.7中的模块C中的判定条件上移到上级模块B中或将模块C整个合并到模块B中。将超出作用域的模块下移。如将图4.5中的模块D移至模块C的下一层上,使模块D处于模块C的控制域中。,图4.5 模块的作用域和控制域,(6)尽量降低模块的接口复杂度。由于复杂的模块接口是导致软件出现错误的主要原因之一,因此在软件设计中应尽量使模块接口简单清晰,如减少接口传送的信息个数以及确保实参和形参的一致性和对应性等。降低模块的接口复杂度,可以提高软件的可读性,减少出现错误的可能性,并有利于软件的测试和维护。(7)设计单入口单出口模块(8)模块功能应该可以预测,4.5.1 描述软件结构用的图形工具 1.HIPO图 HIPO(Hierarchy Plus Input/Processing/Output)图是IBM公司在20世纪70年代发展起来的用于描述软件结构的图形工具。它实质上是在描述软件总体模块结构的层次图(H图)的基础上,加入了用于描述每个模块输入/输出数据和处理功能的IPO图,因此它的中文全名为层次图加输入/处理/输出图。,4.5 软件结构设计方法,1)HIPO图中的H图 H图用于在体系结构设计过程中描绘软件的层次结构。在H图中,每一个矩形框代表一个模块,图中最顶层的矩形框表示系统中的主控模块,矩形框之间的连线用于表示模块之间的调用关系。为了使H图更具有可追踪性,可以为除顶层矩形框以外的其他矩形框加上能反映层次关系的编号。H图比较适用于自顶向下进行分解的软件结构设计方法。工资计算系统的H图如下图所示。,图4.6 工资计算系统的H图,2)IPO图 IPO图能够方便、清晰地描绘出模块的输入数据、加工和输出数据之间的关系。与层次图中每个矩形框相对应,应该有一张IPO图描述该矩形框所代表的模块的具体处理过程,作为对层次图中内容的补充说明。IPO图的基本形式为:在图中左边的框中列出模块涉及的所有输入数据,在中间的框中列出主要的加工,在右边的框中列出处理后产生的输出数据;图中的箭头用于指明输入数据、加工和输出结果之间的关系。工资计算系统中的计算工资模块的IPO图如图4.7所示。,图4.7 计算工资模块的IPO图,2.结构图 在软件工程中,软件结构经常采用20世纪70年代中期由Yourdon等人提出的结构图(SC,Structure Chart)这种图形工具来表示。结构图能够描述出软件系统的模块层次结构,清楚地反映出程序中各模块之间的调用关系和联系。结构图中的基本符号及其含义见表。,表4.1 结构图中的基本符号,4.5.2 面向数据流的软件结构设计方法,1、数据流图的类型 面向数据流的体系设计方法能够方便地将需求分析阶段生成的数据流图转换成设计阶段所需的软件结构。但对于不同类型的数据流图,转换得到的软件结构也不同,因此有必要首先研究一下数据流图的典型形式。根据数据流图的结构特点通常可将数据流图划分为如下两个基本类型。,(1)变换型数据流图 变换型数据流图呈现出的结构特点为:由(逻辑)输入、变换中心和(逻辑)输出三部分组成,如图4.8所示。该类型数据流图所描述的加工过程为:首先,外部数据沿逻辑输入路径进入系统,同时数据的形式由外部形式转化为内部形式;接着,数据被送往变换中心进行加工处理;最后,经过加工得到的结果数据的内部形式被转换为外部形式并沿逻辑输出路径离开系统。可以看出,变换型数据流图反映的是一个顺序结构的加工过程。,图4.8 变换型数据流图的基本模型,(2)事务型数据流图 原则上,所有基本系统模型都属于变换型,但其中有一类具有特殊形态的数据流图又被单独划分为事务型。事务型数据流图呈现出的结构特点为:输入流在经过某个被称为“事务中心”的加工时被分离为多个发散的输出流,形成多个平行的加工处理路径,如图4.9所示。该类型数据流图所描述的加工过程为:外部数据沿输入通路进入系统后,被送往事务中心;事务中心接收输入数据并分析确定其类型;最后根据所确定的类型为数据选择其中的一条加工路径。,图4.9 事务型数据流图的基本模型,2、面向数据流的软件结构设计过程 运用面向数据流的方法进行软件体系结构的设计时,应该首先对需求分析阶段得到的数据流图进行复查,必要时进行修改和精化;接着在仔细分析系统数据流图的基础上,确定数据流图的类型,并按照相应的设计步骤将数据流图转化为软件结构;最后还要根据体系结构设计的原则对得到的软件结构进行优化和改进。面向数据流的体系结构设计过程如图4.10所示。,图4.10 面向数据流的体系结构设计过程,一般来说,大多数系统的加工问题被表示为变换型,可采用变换分析设计方法建立系统的软件结构,但当数据流图具有明显的事务特点时,则应采用事务分析技术进行处理。变换分析设计方法与事务分析设计方法类似,都遵循图4.10所示的设计过程,主要差别仅在于由数据流图向软件结构的映射方法不同。对于一个复杂的系统,数据流图中可能既存在变换流又存在事务流,这时应当根据数据流图的主要处理功能,选择一个面向全局的、涉及整个软件系统的总体类型,映射得到系统的整体软件结构。此外,再对局部范围内的数据流图进行具体研究,确定它们各自的类型并分别处理,得到系统的局部软件结构。,(1)变换分析设计 对于变换型的数据流图,应按照变换分析设计的方法建立系统的结构图。下面以图4.11所示的工资计算系统数据流图为例来介绍变换分析建立软件结构的具体步骤。,A 划分边界,区分系统的输入、变换中心和输出部分。变换中心在图中往往是多股数据流汇集的地方,经验丰富的设计人员通常可根据其特征直接确定系统的变换中心。另外,下述方法可帮助设计人员确定系统的输入和输出:从数据流图的物理输入端出发,沿着数据流方向逐步向系统内部移动,直至遇到不能被看作是系统输入的数据流为止,则此数据流之前的部分即为系统的输入;同理,从数据流图的物理输出端出发,逆着数据流方向逐步向系统内部移动,直至遇到不能被看作是系统输出的数据流为止,则该数据流之后的部分即为系统的输出;夹在输入和输出之间的部分就是系统的变换中心。,图4.11 进行了边界划分的工资计算系统数据流图,B 完成第一级分解,设计系统的上层模块。这一步主要是确定软件结构的顶层和第一层。任何系统的顶层都只含一个用于控制的主模块。变换型数据流图对应的软件结构的第一层一般由输入、变换和输出三种模块组成。系统中的每个逻辑输入对应一个输入模块,完成为主模块提供数据的功能;每一个逻辑输出对应一个输出模块,完成为主模块输出数据的功能;变换中心对应一个变换模块,完成将系统的逻辑输入转换为逻辑输出的功能。工资计算系统的一级分解结果如图4.12所示。,图4.12 工资计算系统的一级分解,C 完成第二级分解,设计输入、变换中心和输出部分的中、下层模块。这一步主要是对上一步确定的软件结构进行逐层细化,为每一个输入、输出模块及变换模块设计下属模块。通常,一个输入模块应包括用于接收数据和转换数据(将接收的数据转换成下级模块所需的形式)的两个下属模块;一个输出模块应包括用于转换数据(将上级模块的处理结果转换成输出所需的形式)和传出数据的两个下属模块;变换模块的分解一般应根据变换中心的组成情况及模块分解的原则来确定下属模块。完成二级分解后,工资计算系统的软件结构如图4.13所示。,图4.13 完成二级分解后的工资计算系统软件结构,(2)事务分析设计,图4.14 进行了边界划分的事务型数据流图,A 划分边界,明确数据流图中的接收路径、事务中心和加工路径。事务中心在数据流图中位于多条加工路径的起点,经过事务中心的数据流被分解为多个发散的数据流,根据这个特征很容易在图中找到系统的事务中心。向事务中心提供数据的路径是系统的接收路径,而从事务中心引出的所有路径都是系统的加工路径,如图4.14中对数据流图的划分。每条加工路径都具有自己的结构特征,可能为变换型,也可能为事务型。如图4.14中,路径1为变换型,路径2为事务型。,B 建立事务型结构的上层模块。事务型流图对应的软件结构的顶层只有一个由事务中心映射得到的总控模块;总控模块有两个下级模块,分别是由接收路径映射得到的接收模块和由全部加工路径映射得到的调度模块。接收模块负责接收系统处理所需的数据,调度模块负责控制下层的所有加工模块。两个模块共同构成了事务型软件结构的第一层。图4.14中,事务型数据流图映射得到的上层软件结构如图4.15所示。,图4.15,C 分解、细化接收路径和加工路径,得到事务型结构的下层模块。由于接收路径通常都具有变换型的特性,因此对事务型结构接收模块的分解方法与对变换型结构输入模块的分解方法相同。对加工路径的分解应按照每一条路径本身的结构特征,分别采用变换分析或事务分析方法进行分解。经过分解后得到的完整的事务型软件结构如图4.16所示。,图4.16 完整的事务型软件结构,3、面向对象的结构设计方法 具体方法参见10章面向对象的开发技术。,图4.17 典型的面向对象设计模型,4.5.3 软件结构设计说明书 软件结构设计说明书是结构设计阶段中最重要的技术文档,其主要内容应包括:(1)引言:用于说明编写本说明书的目的、背景,定义所用到的术语和缩略语,以及列出文档中所引用的参考资料等。(2)总体设计:用于说明软件的需求规定、运行环境要求、处理流程及软件体系结构等。(3)运行设计:用于说明软件的运行模块组合、运行控制方式及运行时间等。,(4)模块设计:用于说明软件中各模块的功能、性能及接口等。(5)数据设计:用于说明软件系统所涉及的数据对象的逻辑数据结构的设计。(6)出错处理设计:用于说明软件系统可能出现的各种错误及可采取的处理措施。,4.7 小 结,软件设计是一个将软件需求转换为软件实现方案的过程,分为结构设计和详细设计两个阶段。结构设计阶段主要完成对系统宏观结构的设计,详细设计阶段则完成系统内部实现细节的确定。系统结构的设计应遵循相应的设计原则,特别是要保证模块的独立性。结构设计过程中通常采用结构图或HIPO图来描述软件的层次结构。在面向数据流的结构设计方法中,将数据流图划分为变换型和事务型两种类型,对于不同类型的数据流图采用不同的映射方法获得系统的软件结构。,