1、第5章 软件设计 第5章 软件设计 5.1 软件设计中的基本概念和原理软件设计中的基本概念和原理 5.2 体系结构设计概述体系结构设计概述 5.3 面向数据流的体系结构设计方法面向数据流的体系结构设计方法 5.4 详细设计概述详细设计概述 5.5 面向数据流的详细设计方法面向数据流的详细设计方法5.6 面向数据结构的设计方法面向数据结构的设计方法5.7 小结小结 第1页,共128页。第5章 软件设计 5.1 5.1 软件设计中的基本概念和原理软件设计中的基本概念和原理 1.1.模块化模块化 所谓模块,是指具有相对独立性的,由数据说明、执行语句等程序对象构成的集合。程序中的每个模块都需要单独命名
2、,通过名字可实现对指定模块的访问。在高级语言中,模块具体表现为函数、子程序、过程等。一个模块具有输入/输出(接口)、功能、内部数据和程序代码四个特征。输入/输出用于实现模块与其他模块间的数据传送,即向模块传入所需的原始数据及从模块传出得到的结果数据。功能指模块所完成的工作。模块的输入/输出和功能构成了模块的外部特征。内部数据是指仅能在模块内部使用的局部量。程序代码用于描述实现模块功能的具体方法和步骤。模块的内部数据和程序代码反映的是模块的内部特征。第2页,共128页。第5章 软件设计 模块化是指将整个程序划分为若干个模块,每个模块用于实现一个特定的功能。划分模块对于解决大型复杂的问题是非常必要
3、的,可以大大降低解决问题的难度。为了说明这一点,我们可对问题复杂性、开发工作量和模块数之间的关系进行以下推理。首先,我们设C(x)为问题x所对应的复杂度函数,E(x)为解决问题x所需要的工作量函数。对于两个问题P1和P2,如果:C(P1)C(P2)即问题P1的复杂度比P2高,则显然有:E(P1)E(P2)即解决问题P1比P2所需的工作量大。第3页,共128页。第5章 软件设计 在人们解决问题的过程中,发现存在有另一个有趣的规律:C(P1+P2)C(P1)+C(P2)即解决由多个问题复合而成的大问题的复杂度大于单独解决各个问题的复杂度之和。也就是说,对于一个复杂问题,将其分解成多个小问题分别解决
4、比较容易。由此我们可以推出:E(P1+P2)E(P1)+E(P2)即将复杂问题分解成若干个小问题,各个击破,所需要的工作量小于直接解决复杂问题所需的工作量。第4页,共128页。第5章 软件设计 根据上面的推理,我们可以得到这样一个结论,模块化可以降低解决问题的复杂度,从而降低软件开发的工作量。但是不是模块划分得越多越好呢?虽然增加程序中的模块数可以降低开发每个模块的工作量,但同时却增加了设计模块接口的工作量。通过图5.1所示的模块数与软件开发成本的关系图中可以看出,当划分的模块数处于最小成本区时,开发软件的总成本最低。虽然目前还不能得到模块数M的精确取值,但总成本曲线对我们进行模块划分具有重要
5、的指导意义。模块化不但可以降低软件开发的难度,而且可以使程序结构清晰,增加易读性和易修改性。此外,模块化还有利于提高代码的可重用性及团队合作开发大型软件的可行性。第5页,共128页。第5章 软件设计 图5.1 模块数与软件开发成本成本(工作量)模块数接口成本软件总成本最小成本区M成本/模块第6页,共128页。第5章 软件设计 2.2.模块独立性模块独立性 1)耦合性 耦合性是对一个软件结构内部不同模块间联系紧密程度的度量指标。模块间的联系越紧密,耦合性就越高,模块的独立性也就越低。由于模块间的联系是通过模块接口实现的,因此,模块耦合性的高低主要取决于模块接口的复杂程度、调用模块的方式以及通过模
6、块接口的数据。模块间的耦合性主要可划分为如下几种类型。第7页,共128页。第5章 软件设计 (1)数据耦合。若两个模块之间仅通过模块参数交换信息,且交换的信息全部为简单数据,则称这种耦合为数据耦合。数据耦合的耦合性最低,通常软件中都包含有数据耦合。数据耦合的例子如下所示:第8页,共128页。第5章 软件设计 sum(int a,int b)int c;c=a+b;return(c);main()int x,y;printf(x+y=%d,sum(x,y);/*主函数与sum函数之间即为数据耦合关系*/第9页,共128页。第5章 软件设计 (2)公共耦合。若两个或多个模块通过引用公共数据相互联系
7、,则称这种耦合为公共耦合。例如,在程序中定义了全局变量,并在多个模块中对全局变量进行了引用,则引用全局变量的多个模块间就具有了公共耦合关系。FORTRAN语言中使用的common语句也会在多个模块间建立公共耦合关系。公共耦合的复杂度随着耦合的模块个数的增加而显著增加。在程序设计中,若两个模块间需要交换的数据较多,仅通过参数传递难以实现时,可以考虑采用公共耦合完成,但一定注意尽量降低公共耦合的程度。第10页,共128页。第5章 软件设计 (3)控制耦合。若模块之间交换的信息中包含有控制信息(尽管有时控制信息是以数据的形式出现的),则称这种耦合为控制耦合。控制耦合是中等程度的耦合,它会增加程序的复
8、杂性。控制耦合的例子如下所示:void output(flag)if(flag)printf(OK!);else printf(NO!);main()int flag;output(flag);/*主函数与output函数之间即为控制耦合关系*/第11页,共128页。第5章 软件设计 (4)内容耦合。若一个模块对另一模块中的内容(包括数据和程序段)进行了直接的引用甚至修改,或通过非正常入口进入到另一模块内部,或一个模块具有多个入口,或两个模块共享一部分代码,则称模块间的这种耦合为内容耦合。内容耦合是所有耦合关系中程度最高的,会使因模块间的联系过于紧密而对后期的开发和维护工作带来很大的麻烦,因此
9、,应坚决避免任何形式的内容耦合。实际上,许多高级程序设计语言在设计时就充分考虑到了内容耦合的危害,因而在规定语法时就已经杜绝了任何形式的内容耦合。耦合是影响软件复杂度的一个重要因素,设计过程中应力求降低程序的耦合性。在以上所介绍的耦合中,数据耦合的程度最低,其次是公共耦合,再其次是控制耦合,程度最高的是内容耦合。第12页,共128页。第5章 软件设计 2)内聚性 内聚性是对一个模块内部各个组成元素之间相互结合的紧密程度的度量指标。模块中组成元素结合的越紧密,模块的内聚性就越高,模块的独立性也就越高。理想的内聚性要求模块的功能应明确、单一,即一个模块只做一件事情。模块的内聚性和耦合性是两个相互对
10、立且又密切相关的概念。事实上,它们是同一事物的两个方面,模块的高内聚性往往就意味着模块间的低耦合性。因为程序中的各个部分必定是有联系的,若将其中密切相关的部分放在同一个模块中,模块间的联系就会降低;反之,若将密切相关的部分分散放在不同的模块之中,模块间的联系必然会加强。在进行模块化设计时,耦合性和内聚性都是必须考虑的重要指标。但经实践证明,保证模块的高内聚性比低耦合性更为重要,在软件设计时应将更多的注意力集中在提高模块的内聚性上。模块的内聚性主要可划分为如下几种不同的类型。第13页,共128页。第5章 软件设计 (1)偶然内聚。若一个模块由多个完成不同任务的语句段组成,各语句段之间的联系十分松
11、散或根本没有任何联系,则称此模块的内聚为偶然内聚。例如,程序中多处出现一些无联系的语句段序列,为了节省内存空间将其组合成为一个模块,这个模块就属于偶然内聚。偶然内聚的模块由于组成部分之间没有实质的联系,因此难于理解和修改,会给软件开发带来很大的困扰。事实上,偶然内聚的模块出错的机率要比其他类型的模块大得多。偶然内聚是内聚程度最低的一种,在软件设计时应尽量避免。第14页,共128页。第5章 软件设计 (2)逻辑内聚。若一个模块可实现多个逻辑上相同或相似的一类功能,则称该模块的内聚为逻辑内聚。例如,将程序中多种不同类型数据的输出放在同一个模块中实现,这个模块就属于逻辑聚合。逻辑内聚比偶然内聚的内聚
12、程度高一些。虽然逻辑聚合模块的组成部分之间有一定的关系,但不同功能混在一起并公用模块中的部分代码,给修改带来了一定的麻烦。另外,为了在调用模块时能选择执行其中的某个功能,需要传递相应的控制参数,因而会造成模块间的控制耦合,降低模块的独立性。第15页,共128页。第5章 软件设计 (3)时间内聚。若一个模块包含了需要在同一时间段中执行的多个任务,则称该模块的内聚为时间内聚。例如,将多个变量的初始化放在同一个模块中实现,或将需要同时使用的多个库文件的打开操作放在同一个模块中,都会产生时间内聚的模块。由于时间内聚模块中的各个部分在时间上的联系,其内聚程度比逻辑内聚高一些。但这样的模块往往会和其他相关
13、模块有着紧密的联系,因而会造成耦合性的增加。第16页,共128页。第5章 软件设计 (4)过程内聚。若一个模块中的各个部分相关,并且必须按特定的次序执行,则称该模块的内聚为过程内聚。在结构化程序中,通常采用程序流程图作为设计软件和确定模块划分的工具,因此,这样得到的模块往往具有过程内聚的特性。(5)通信内聚。若一个模块中的各个部分使用同一个输入数据或产生同一个输出数据,则称该模块的内聚为通信内聚。由于通信内聚模块中的各个部分都与某个共同的数据密切相关,因此内聚性高于前几种内聚。第17页,共128页。第5章 软件设计 (6)顺序内聚。若一个模块中的各个部分都与同一个功能密切相关,并且必须按照先后
14、顺序执行(通常前一个部分的输出数据就是后一个部分的输入数据),则称该模块的内聚为顺序内聚。例如,在一个处理学生成绩的模块中,前一个部分根据成绩统计出及格的学生人数,后一个部分根据及格人数计算出学生的及格率。根据数据流图划分出的模块通常都是顺序内聚的模块。由于顺序内聚模块中的各个部分在功能和执行顺序上都密切相关,因此内聚程度很高且易于理解。第18页,共128页。第5章 软件设计 (7)功能内聚。若一个模块中各个组成部分构成一个整体并共同完成一个单一的功能,则称该模块的内聚为功能内聚。由于功能内聚模块中的各个部分关系非常密切,构成一个不可分割的整体,因此功能内聚是所有内聚中内聚程度最高的一种。在以
15、上所介绍的七种内聚中,按照内聚性从低到高进行排列的结果如图5.2所示。第19页,共128页。第5章 软件设计 偶然内聚逻辑内聚时间内聚低内聚过程内聚通信内聚中内聚顺序内聚功能内聚高内聚低高图图5.2 内聚性的排列内聚性的排列 第20页,共128页。第5章 软件设计 3.3.抽象抽象 抽象是人类在解决复杂问题时经常采用的一种思维方式,它是指将现实世界中具有共性的一类事物的相似的、本质的方面集中概括起来,而暂时忽略它们之间的细节差异。在软件开发中运用抽象的概念,可以将复杂问题的求解过程分层,在不同的抽象层上实现难度的分解。在抽象级别较高的层次上,可以将琐碎的细节的信息暂时隐藏起来,以利于解决系统中
16、的全局性的问题。软件开发过程中从问题定义到最终的软件生成,每一阶段都是在前一阶段基础上对软件解法的抽象层上的一次求精和细化。第21页,共128页。第5章 软件设计 结构化程序中自顶向下、逐步求精的模块划分思想正是人类思维中运用抽象方法解决复杂问题的体现。软件结构中顶层的模块抽象级别最高,控制并协调软件的主要功能且影响全局;软件结构中位于底层的模块抽象级别最低,具体实现数据的处理过程。采用自顶向下、由抽象到具体的思维方式,不但降低了软件开发中每个阶段的工作难度,简化了软件的设计和实现过程,还有助于提高软件的可读性、可测试性和可维护性。此外,在程序设计中运用抽象的方法还能够提高代码的可重用性。第2
17、2页,共128页。第5章 软件设计 4.4.信息隐蔽信息隐蔽 信息隐蔽是指一个模块将自身的内部信息向其他模块隐藏起来,以避免其他模块不恰当的访问和修改,只有对那些为了完成系统功能所必须的数据交换才被允许在模块间进行。信息隐蔽的目的主要是为了提高模块的独立性,减少将一个模块中的错误扩散到其他模块的机会。但是需要强调一点,信息隐蔽并不意味着某个模块中的内部信息对其他模块来说是完全不可见或不能使用的,而是说模块之间的信息传递只能通过合法的调用接口来实现。显然,信息隐蔽对提高软件的可读性和可维护性都是非常重要的。第23页,共128页。第5章 软件设计 5.2 5.2 体系结构设计概述体系结构设计概述5
18、.2.1 5.2.1 体系结构设计的任务体系结构设计的任务 在体系结构设计过程中,首先要根据需求分析阶段产生的成果寻求实现目标系统的各种可能的方案,然后由系统分析员对所有可能的方案进行综合分析比较,从中选择出一个最佳方案向用户推荐。在与用户达成共识之后,系统分析员就可以着手对选择出的最佳方案进行体系结构的设计,并为软件确定数据结构及设计数据库。体系结构设计阶段结束时,系统分析员需要提交软件的体系结构说明书并参加该阶段的评审。体系结构设计的主要任务有如下四点。第24页,共128页。第5章 软件设计 1.1.软件体系结构设计软件体系结构设计 设计软件的体系结构需要在对需求分析阶段生成的数据流图进一
19、步分析和精化的基础上,首先将系统按照功能划分为模块,接着需要确定模块之间的调用关系及其接口,最后还应该对划分的结果进行优化和调整。良好的软件结构设计对详细设计及编码阶段的工作都是至关重要的。第25页,共128页。第5章 软件设计 2.2.数据结构和数据库设计数据结构和数据库设计 体系结构设计中应对需求分析阶段所生成的数据字典加以细化,从计算机技术实现的角度出发,确定软件涉及的文件系统及各种数据的结构。主要包括确定输入、输出文件的数据结构及确定算法所需的逻辑数据结构等。在需求分析阶段仅为系统所需的数据库建立了概念数据模型(最常采用的是E-R模型)。体系结构设计阶段需要将原本独立于数据库实现的概念
20、模型与具体的数据库管理系统的特征结合起来,建立数据库的逻辑结构,主要包括确定数据库的模式、子模式及对数据库进行规范和优化等。第26页,共128页。第5章 软件设计 3.3.系统可靠性、安全性设计系统可靠性、安全性设计 可靠性设计也称为质量设计,目的是为了保证程序及其文档具有较高的正确性和容错性,并对可能出现的错误易于修改和维护。安全性设计的主要目的是为了增强系统的自我防护能力和运行的稳定性,防止系统遭受到有意或无意地入侵和破坏,保证系统在安全的环境下正常地工作。第27页,共128页。第5章 软件设计 4.4.编写文档,参加复审编写文档,参加复审 体系结构设计阶段应交付的文档通常包括:体系结构设
21、计说明书、用户手册、数据库设计说明书及系统初步测试计划。(1)体系结构设计说明书:给出系统总体结构设计的结果,为系统的详细设计提供基础。(2)用户手册:根据体系结构设计成果,对需求分析阶段编写的用户手册进行补充和修改。(3)测试计划:明确测试中应采用的策略、方案、预期的测试结果及测试的进度安排。第28页,共128页。第5章 软件设计 (4)数据库设计说明书:主要用于给出目标系统中数据库管理系统的选择及逻辑结构等的设计结果。体系结构设计阶段复审的重点主要是系统的总体结构、模块划分和内/外接口等方面,复审的对象就是该阶段的设计文档。由于体系结构设计中的微小失误可能会导致软件开发中的重大问题,因此复
22、审一定要按严格的步骤,通过正式会议的方式进行,争取尽可能地及早发现设计中的缺陷和错误。除软件开发人员以外,体系结构设计复审必须有用户参加,必要时还可以邀请相关领域的专家参加会议。第29页,共128页。第5章 软件设计 5.2.2 5.2.2 体系结构设计中可采用的工具体系结构设计中可采用的工具 1.HIPO 1.HIPO图图 HIPO(Hierarchy Plus Input/Processing/Output)图是IBM公司在20世纪70年代发展起来的用于描述软件结构的图形工具。它实质上是在描述软件总体模块结构的层次图(H图)的基础上,加入了用于描述每个模块输入/输出数据和处理功能的IPO图
23、,因此它的中文全名为层次图加输入/处理/输出图。第30页,共128页。第5章 软件设计 1)HIPO图中的H图 H图用于在体系结构设计过程中描绘软件的层次结构。在H图中,每一个矩形框代表一个模块,图中最顶层的矩形框表示系统中的主控模块,矩形框之间的连线用于表示模块之间的调用关系。为了使H图更具有可追踪性,可以为除顶层矩形框以外的其他矩形框加上能反映层次关系的编号。H图比较适用于自顶向下进行分解的软件结构设计方法。工资计算系统的H图如图5.3所示。第31页,共128页。第5章 软件设计 图5.3 工资计算系统的H图计算出勤奖1.1.2.1计算业绩奖1.1.2.2计算工资档案各基本数据项之和1.1
24、.1计算奖金1.1.2计算应发工资1.1计算水电扣款1.2.1计算缺勤扣款1.2.2计算所得税扣款1.2.3计算扣款1.2计算实发工资1.3计算工资1查询职工账号2.1生成工资存款清单2.2工资转存2打印工资清单3工资计算系统第32页,共128页。第5章 软件设计 2)IPO2)IPO图图 IPO图能够方便、清晰地描绘出模块的输入数据、加工和输出数据之间的关系。与层次图中每个矩形框相对应,应该有一张IPO图描述该矩形框所代表的模块的具体处理过程,作为对层次图中内容的补充说明。IPO图的基本形式为:在图中左边的框中列出模块涉及的所有输入数据,在中间的框中列出主要的加工,在右边的框中列出处理后产生
25、的输出数据;图中的箭头用于指明输入数据、加工和输出结果之间的关系。工资计算系统中的计算工资模块的IPO图如图5.4所示。第33页,共128页。第5章 软件设计 图5.4 计算工资模块的IPO图业绩表出勤表工资档案文件奖惩条例水电扣款表计算奖金计算应发工资计算扣款计算实发工资奖金发放表应发工资表扣款表工资清单实发工资表第34页,共128页。第5章 软件设计 2.2.结构图结构图 在软件工程中,软件结构经常采用20世纪70年代中期由Yourdon等人提出的结构图(SC,Structure Chart)这种图形工具来表示。结构图能够描述出软件系统的模块层次结构,清楚地反映出程序中各模块之间的调用关系
26、和联系。结构图中的基本符号及其含义见表5.1。第35页,共128页。第5章 软件设计 表表5.1 5.1 结构图中的基本符号结构图中的基本符号ABCABC符 号含 义用于表示模块,方框中标明模块的名称用于描述模块之间的调用关系用于表示模块调用过程中传递的信息,箭头上标明信息的名称;箭头尾部为空心圆表示传递的信息是数据,若为实心圆则表示传递的是控制信息 表示模块A选择调用模块B或模块C表示模块A循环调用模块B和模块C第36页,共128页。第5章 软件设计 5.2.3 5.2.3 体系结构设计的原则体系结构设计的原则 体系结构设计的原则有如下6点。(1)降低模块的耦合性,提高模块的内聚性。为了提高
27、软件中各个模块的独立性,提高程序的可读性、可测试性和可维护性,在软件体系结构设计时应尽可能采用内聚性高的模块,如最好实现功能内聚;尽量只使用数据耦合,限制公共耦合的使用,避免控制耦合的使用,杜绝内容耦合的出现。第37页,共128页。第5章 软件设计 (2)保持适中的模块规模。程序中模块的规模过大,会降低程序的可读性;而模块规模过小,势必会导致程序中的模块数目过多,增加接口的复杂性。对于模块的适当规模并没有严格的规定,但普遍的观点是模块中的语句数最好保持在10100之间。为了使模块的规模适中,在保证模块独立性的前提下,可对程序中规模过小的模块进行合并或对规模过大的模块进行分解。第38页,共128
28、页。第5章 软件设计 (3)模块应具有高扇入和适当的扇出。在模块调用中,某个模块的上级模块数被称为该模块的扇入(如图5.5(a)所示,模块M的扇入数为n);而某个模块可以调用的下级模块数被称为该模块的扇出(如图5.5(b)所示,模块M的扇出数为k)。显然,一个模块的扇入表明了共有多少个模块需要调用该模块,而其扇出表明了该模块可以控制的下级模块的数目。第39页,共128页。第5章 软件设计 图5.5 模块的扇入和扇出(a)扇入;(b)扇出M1M2MnM(a)(b)M1M2MkM第40页,共128页。第5章 软件设计 模块的扇入越大,则说明共享该模块的上级模块数越多,或者说该模块在程序中的重用性越
29、高,这正是程序设计所追求的目标之一。当多个模块具有一部分相同功能时,应将这部分相同的功能分离出来,编写成独立的模块供需要的模块调用。通过消除不同模块中的重复内容,提高代码的可重用性,可以减少程序的总代码量,便于程序的测试和维护。第41页,共128页。第5章 软件设计 模块的扇出若过大,如在一个模块中要调用八个下级模块,则会使该模块的调用控制过于复杂。这种现象发生的原因通常都是由于设计阶段,模块细化的过程中,分解速度过快造成的。最常见的解决办法是通过在此模块和下级模块间增加一个中间层来控制模块分解的速度。模块的扇出过小,如扇出为1(下级模块层中只有一个模块),在系统设计中通常是不可取的。常见的解
30、决方法是考虑将其合并到上级模块中。但若合并会影响模块的独立性,则将其保留下来也未尝不可。根据实践经验,设计良好的典型系统中,模块的平均扇出通常为3或4。第42页,共128页。第5章 软件设计 可以看出:在一个好的软件结构中,模块应具有较高的扇入和适当的扇出。但绝不能为了单纯追求高扇入或合适的扇出而破坏了模块的独立性。此外,经过对大量软件系统的研究后发现,在设计良好的软件结构中,通常顶层的扇出数较大,中间层的扇出数较小,底层的扇入数较大,如图5.6所示。第43页,共128页。第5章 软件设计 图5.6 软件结构图示例 第44页,共128页。第5章 软件设计 (4)软件结构中的深度和宽度不宜过大。
31、所谓深度,是指软件体系结构中控制的层数,它能够粗略地反映出软件系统的规模和复杂程度;所谓宽度,是指软件体系结构内同一层次上模块个数的最大值,通常宽度越大的系统越复杂。如图5.6所示的软件结构图中,深度为5,宽度为8。深度在程序中表现为模块的嵌套调用,嵌套的层数越多,程序就越复杂,程序的可理解性也就随之下降。对宽度影响最大的因素是模块的扇出,即模块可以调用的下级模块数越多,软件结构的宽度就越大。深度过大可通过将结构中过于简单的模块分层与上一级模块合并来解决;而宽度过大则可通过增加中间层来解决。显然,软件结构中的深度和宽度是相互对立的两个方面,降低深度会引起宽度的增加,而降低宽度又会带来深度的增加
32、。第45页,共128页。第5章 软件设计 (5)模块的作用域应处于其控制域范围之内。模块的作用域是指受该模块内一个判定条件影响的所有模块范围。模块的控制域是指该模块本身以及所有该模块的下属模块(包括该模块可以直接调用的下级模块和可以间接调用的更下层的模块)。例如,在图5.7中,模块C的控制域为模块C、E和F;若在模块C中存在一个对模块D、E和F均有影响的判定条件,即模块C的作用域为模块C、D、E和F(图中带阴影的模块),则显然模块C的作用域超出了其作用域。由于模块D在模块C的作用域中,因此模块C对模块D的控制信息必然要通过上级模块B进行传递,这样不但会增加模块间的耦合性,而且会给模块的维护和修
33、改带来麻烦(若要修改模块C,可能会对不在它控制域中的模块D造成影响)。因此,软件设计时应使各个模块的作用域处于其控制域范围之内。若发现不符合此设计原则的模块,可通过下面的方法进行改进:第46页,共128页。第5章 软件设计 将判定位置上移。如将图5.7中的模块C中的判定条件上移到上级模块B中或将模块C整个合并到模块B中。将超出作用域的模块下移。如将图5.7中的模块D移至模块C的下一层上,使模块D处于模块C的控制域中。第47页,共128页。第5章 软件设计 MABCDEF图图5.7 模块的作用域和控制域模块的作用域和控制域 第48页,共128页。第5章 软件设计 (6)尽量降低模块的接口复杂度。
34、由于复杂的模块接口是导致软件出现错误的主要原因之一,因此在软件设计中应尽量使模块接口简单清晰,如减少接口传送的信息个数以及确保实参和形参的一致性和对应性等。降低模块的接口复杂度,可以提高软件的可读性,减少出现错误的可能性,并有利于软件的测试和维护。第49页,共128页。第5章 软件设计 5.2.4 5.2.4 体系结构设计说明书体系结构设计说明书 体系结构设计说明书是体系结构设计阶段中最重要的技术文档,其主要内容应包括:(1)引言:用于说明编写本说明书的目的、背景,定义所用到的术语和缩略语,以及列出文档中所引用的参考资料等。(2)总体设计:用于说明软件的需求规定、运行环境要求、处理流程及软件体
35、系结构等。(3)运行设计:用于说明软件的运行模块组合、运行控制方式及运行时间等。第50页,共128页。第5章 软件设计 (4)模块设计:用于说明软件中各模块的功能、性能及接口等。(5)数据设计:用于说明软件系统所涉及的数据对象的逻辑数据结构的设计。(6)出错处理设计:用于说明软件系统可能出现的各种错误及可采取的处理措施。第51页,共128页。第5章 软件设计 5.3 5.3 面向数据流的体系结构设计方法面向数据流的体系结构设计方法5.3.1 5.3.1 数据流图的类型数据流图的类型 面向数据流的体系设计方法能够方便地将需求分析阶段生成的数据流图转换成设计阶段所需的软件结构。但对于不同类型的数据
36、流图,转换得到的软件结构也不同,因此有必要首先研究一下数据流图的典型形式。根据数据流图的结构特点通常可将数据流图划分为如下两个基本类型。第52页,共128页。第5章 软件设计 1.1.变换型数据流图变换型数据流图 变换型数据流图呈现出的结构特点为:由(逻辑)输入、变换中心和(逻辑)输出三部分组成,如图5.8所示。该类型数据流图所描述的加工过程为:首先,外部数据沿逻辑输入路径进入系统,同时数据的形式由外部形式转化为内部形式;接着,数据被送往变换中心进行加工处理;最后,经过加工得到的结果数据的内部形式被转换为外部形式并沿逻辑输出路径离开系统。可以看出,变换型数据流图反映的是一个顺序结构的加工过程。
37、第53页,共128页。第5章 软件设计 变换中心变换输入输出图图5.8 变换型数据流图的基本模型变换型数据流图的基本模型 第54页,共128页。第5章 软件设计 2.2.事务型数据流图事务型数据流图 原则上,所有基本系统模型都属于变换型,但其中有一类具有特殊形态的数据流图又被单独划分为事务型。事务型数据流图呈现出的结构特点为:输入流在经过某个被称为“事务中心”的加工时被分离为多个发散的输出流,形成多个平行的加工处理路径,如图5.9所示。该类型数据流图所描述的加工过程为:外部数据沿输入通路进入系统后,被送往事务中心;事务中心接收输入数据并分析确定其类型;最后根据所确定的类型为数据选择其中的一条加
38、工路径。第55页,共128页。第5章 软件设计 图5.9 事务型数据流图的基本模型事务中心输入流接收路径加工路径第56页,共128页。第5章 软件设计 5.3.2 5.3.2 面向数据流的体系结构设计过程面向数据流的体系结构设计过程 运用面向数据流的方法进行软件体系结构的设计时,应该首先对需求分析阶段得到的数据流图进行复查,必要时进行修改和精化;接着在仔细分析系统数据流图的基础上,确定数据流图的类型,并按照相应的设计步骤将数据流图转化为软件结构;最后还要根据体系结构设计的原则对得到的软件结构进行优化和改进。面向数据流的体系结构设计过程如图5.10所示。第57页,共128页。第5章 软件设计 图
39、5.10 面向数据流的体系结构设计过程事务流变换流精化数据流图区分事务中心、接收路径及加工路径区分变换中心、输入及输出部分映射成事务结构映射成变换结构详细设计根据体系结构设计基本原则优化软件结构导出接口描述和全程数据结构复查事务分析变换分析流类型第58页,共128页。第5章 软件设计 一般来说,大多数系统的加工问题被表示为变换型,可采用变换分析设计方法建立系统的软件结构,但当数据流图具有明显的事务特点时,则应采用事务分析技术进行处理。变换分析设计方法与事务分析设计方法类似,都遵循图5.10所示的设计过程,主要差别仅在于由数据流图向软件结构的映射方法不同。对于一个复杂的系统,数据流图中可能既存在
40、变换流又存在事务流,这时应当根据数据流图的主要处理功能,选择一个面向全局的、涉及整个软件系统的总体类型,映射得到系统的整体软件结构。此外,再对局部范围内的数据流图进行具体研究,确定它们各自的类型并分别处理,得到系统的局部软件结构。第59页,共128页。第5章 软件设计 1.1.变换分析设计变换分析设计 对于变换型的数据流图,应按照变换分析设计的方法建立系统的结构图。下面以图5.11所示的工资计算系统数据流图为例来介绍变换分析建立软件结构的具体步骤。第60页,共128页。第5章 软件设计 (1)划分边界,区分系统的输入、变换中心和输出部分。变换中心在图中往往是多股数据流汇集的地方,经验丰富的设计
41、人员通常可根据其特征直接确定系统的变换中心。另外,下述方法可帮助设计人员确定系统的输入和输出:从数据流图的物理输入端出发,沿着数据流方向逐步向系统内部移动,直至遇到不能被看作是系统输入的数据流为止,则此数据流之前的部分即为系统的输入;同理,从数据流图的物理输出端出发,逆着数据流方向逐步向系统内部移动,直至遇到不能被看作是系统输出的数据流为止,则该数据流之后的部分即为系统的输出;夹在输入和输出之间的部分就是系统的变换中心。工资计算系统的数据流图的划分如图5.11所示。第61页,共128页。第5章 软件设计 图5.11 进行了边界划分的工资计算系统数据流图奖金发放表缺勤扣款表工资档案F2应发工资表
42、所得税扣款后勤部门水电扣款表工资清单F3实发工资表工资条职工打印工资清单职工个人工资账号清单F4查找职工银行工资账号实发工资银行工资存款清单账号计算出勤奖奖惩条例F1统计出勤、请假及旷工时数人事部门出勤表业绩表计算缺勤扣款计算业绩奖业绩奖出勤奖出勤时数请假及旷工时数基本工资计算各项基本数据之和计算应发工资生成工资存款清单计算所得税计算各项奖金之和计算实发工资第62页,共128页。第5章 软件设计 (2)完成第一级分解,设计系统的上层模块。这一步主要是确定软件结构的顶层和第一层。任何系统的顶层都只含一个用于控制的主模块。变换型数据流图对应的软件结构的第一层一般由输入、变换和输出三种模块组成。系统
43、中的每个逻辑输入对应一个输入模块,完成为主模块提供数据的功能;每一个逻辑输出对应一个输出模块,完成为主模块输出数据的功能;变换中心对应一个变换模块,完成将系统的逻辑输入转换为逻辑输出的功能。工资计算系统的一级分解结果如图5.12所示。第63页,共128页。第5章 软件设计 工资计算系统取得基本数据计算工资输出计算结果图图5.12 工资计算系统的一级分解工资计算系统的一级分解 第64页,共128页。第5章 软件设计 (3)完成第二级分解,设计输入、变换中心和输出部分的中、下层模块。这一步主要是对上一步确定的软件结构进行逐层细化,为每一个输入、输出模块及变换模块设计下属模块。通常,一个输入模块应包
44、括用于接收数据和转换数据(将接收的数据转换成下级模块所需的形式)的两个下属模块;一个输出模块应包括用于转换数据(将上级模块的处理结果转换成输出所需的形式)和传出数据的两个下属模块;变换模块的分解没有固定的方法,一般应根据变换中心的组成情况及模块分解的原则来确定下属模块。完成二级分解后,工资计算系统的软件结构如图5.13所示(图中省略了模块调用传递的信息)。第65页,共128页。第5章 软件设计 图5.13 完成二级分解后的工资计算系统软件结构取得水电扣款计算出勤奖、缺勤扣款计算业绩奖计算基本工资读水电扣款表读考勤表读业绩表读工资档案取得基本数据计算应发工资计算实发工资计算奖金之和计算所得税计算
45、工资生成工资存款清单查找职工银行工资账号打印工资清单工资计算系统输出计算结果第66页,共128页。第5章 软件设计 2.2.事务分析设计事务分析设计图5.14 进行了边界划分的事务型数据流图 AEGBCIJKH接收路径事务中心F加工路径 2加工路径 1第67页,共128页。第5章 软件设计 (1)划分边界,明确数据流图中的接收路径、事务中心和加工路径。事务中心在数据流图中位于多条加工路径的起点,经过事务中心的数据流被分解为多个发散的数据流,根据这个特征很容易在图中找到系统的事务中心。向事务中心提供数据的路径是系统的接收路径,而从事务中心引出的所有路径都是系统的加工路径,如图5.14中对数据流图
46、的划分。每条加工路径都具有自己的结构特征,可能为变换型,也可能为事务型。如图5.14中,路径1为变换型,路径2为事务型。第68页,共128页。第5章 软件设计 (2)建立事务型结构的上层模块。事务型流图对应的软件结构的顶层只有一个由事务中心映射得到的总控模块;总控模块有两个下级模块,分别是由接收路径映射得到的接收模块和由全部加工路径映射得到的调度模块。接收模块负责接收系统处理所需的数据,调度模块负责控制下层的所有加工模块。两个模块共同构成了事务型软件结构的第一层。图5.14中,事务型数据流图映射得到的上层软件结构如图5.15所示。第69页,共128页。第5章 软件设计 图5.15总控接收调度第
47、70页,共128页。第5章 软件设计 (3)分解、细化接收路径和加工路径,得到事务型结构的下层模块。由于接收路径通常都具有变换型的特性,因此对事务型结构接收模块的分解方法与对变换型结构输入模块的分解方法相同。对加工路径的分解应按照每一条路径本身的结构特征,分别采用变换分析或事务分析方法进行分解。经过分解后得到的完整的事务型软件结构如图5.16所示。第71页,共128页。第5章 软件设计 图5.16 完整的事务型软件结构调度IKJ总控BA事务1事务2EFGH第72页,共128页。第5章 软件设计 3.3.软件结构的改进和优化软件结构的改进和优化 为了使最终生成的软件系统具有良好的风格及较高的效率
48、,应在软件的早期设计阶段尽量地对软件结构进行优化。因此在建立软件结构后,软件设计人员需要按照体系结构设计的基本原则对其进行必要的改进和调整。软件结构的优化应该力求在保证模块划分合理的前提下,减少模块的数量、提高模块的内聚性及降低模块的耦合性,设计出具有良好特性的软件结构。第73页,共128页。第5章 软件设计 5.4 5.4 详细设计概述详细设计概述5.4.1 5.4.1 详细设计的任务详细设计的任务 详细设计的任务主要有如下五点。(1)确定每个模块的具体算法。根据体系结构设计所建立的系统软件结构,为划分的每个模块确定具体的算法,并选择某种表达工具将算法的详细处理过程描述出来。第74页,共12
49、8页。第5章 软件设计 (2)确定每个模块的内部数据结构及数据库的物理结构。为系统中的所有模块确定并构造算法实现所需的内部数据结构;根据前一阶段确定的数据库的逻辑结构,对数据库的存储结构、存取方法等物理结构进行设计。(3)确定模块接口的具体细节。按照模块的功能要求,确定模块接口的详细信息,包括模块之间的接口信息、模块与系统外部的接口信息及用户界面等。第75页,共128页。第5章 软件设计 (4)为每个模块设计一组测试用例。由于负责详细设计的软件人员对模块的实现细节十分清楚,因此由他们在完成详细设计后提出模块的测试要求是非常恰当和有效的。(5)编写文档,参加复审。详细设计阶段的成果主要以详细设计
50、说明书的形式保留下来,在通过复审对其进行改进和完善后作为编码阶段进行程序设计的主要依据。第76页,共128页。第5章 软件设计 5.4.2 5.4.2 详细设计可采用的工具详细设计可采用的工具 1.1.程序流程图程序流程图 程序流程图是最早出现且使用较为广泛的算法表达工具之一,能够有效地描述问题求解过程中的程序逻辑结构。程序流程图中经常使用的基本符号如图5.17所示。图5.17 程序流程图中的基本符号(a)一般处理框;(b)输入/输出框;(c)判断框;(d)流程线;(e)起止框(a)(b)(c)(d)(e)第77页,共128页。第5章 软件设计 程序流程图的主要优点在于对程序的控制流程描述直观