1、软件设计综述报告软件设计包括一套原理、概念和实践。明确软件设计目标是软件设计的第一步。软件设计目标明确了最终的软件系统应该拥有的质量属性。软件设计的目标涉及性能、可靠性、成本、维护等多个方面的目标。1.1软件设计的目标 软件设计的目标应从用户那里得到,确定了软件最终应拥有的功能。可以从需求规格说明书中选择重要的质量属性,作为设计目标,如性能目标、可靠目标等。而成本和维护方面往往从客户和供应商那里得到。1.1.1性能准则 性能准则包括对系统速度和空间的需求。系统应该是能够发现请求并及时响应这些请求。1.1.2可靠性准则 可靠性准则决定了对减少系统崩溃以及随后所造成危害所做的努力程度。1.1.3成
2、本准则 成本准则包括开发、配置和管理系统的成本。当新系统更新旧系统时,应该考虑确保向后兼容,或减少新系统移植的开销,同时需要考虑在多种不同成本之间做出权衡。1.1.4维护准则 维护准则确定在开发完成后再改变系统的困难程度。这些准则很难进行优化和事先规划,因为很少能够清晰的给出项目成功的程度和系统的可操作的时间周期。1.1.5最终用户准则 最终用户准则包括从用户的视点出发所需的属性,但并没有覆盖性能准则和可靠性准则。1.2软件设计的任务 软件设计的主要任务是要解决如何做的问题,要在需求分析的基础上,建立各种设计模型,并通过对设计模型的分析和评估,确定模型是否满足需求。软件设计是将用户需求准确的转
3、化成为最终的软件产品的唯一途径,在需求到构造之间起到了桥梁作用。1.2.1软件设计的阶段和任务 从工程管理的角度将软件设计分为两个阶段:概要设计阶段和详细设计阶段。从技术的角度,采用的方法不同,设计的内容也会有所不同。传统的结构化的方法将软件设计划分为体系结构设计、数据设计、接口设计和过程设计。(1) 体系结构设计:体系结构设计定义软件的主要结构元素及其之间的关系。体系结构设计表可以从系统规格说明、分析模型及体系结构的风格导出。(2) 类设计:类设计对分析阶段所建立的分析类模型进行细化,转化为设计类的实现及软件实现所要求的数据结构。(3) 数据设计:传统方法主要根据需求阶段所建立的实体-关系图
4、来确定软件设计的文件系统的结构及数据库的表结构。(4) 接口设计:接口设计描述用户界面,软件和其他硬件设备、其他软件系统及使用人员的外部接口。(5) 构件级设计:构件级设计将软件体系结构的结构元素变换为对软件构件的过程性的描述。接口设计类设计(00方法)详细设计过程设计(传统方法)构件级设计(000方法)需要设计体系结构设计数据设计管理观点技术观点图1 从技术和管理的角度看设计的关系(6) 过程设计:过程设计的主要工作是确定软件各个组成部分内的算法及内部数据结构,并选定某种过程的表达式来描述各种算法。1.2.2结构化设计与结构化分析的关系 软件设计必须依据对软件的需求来进行,结构化分析的结果为
5、结构化设计提供了最基本的输入信息。(1)研究、分析和审查数据流图。根据穿越系统边界的信息流初步确定系统与外部接口。(2)根据数据流图决定问题的类型。数据处理问题通常有两种类型:变换型和事务型。针对两种不同的类型分别进行分析处理。(3)由数据流图推导出系统的初始结构图。(4)利用一些启发式原则来改进系统的初始结构图,直到得到符合要求的结构图为止。(5)根据分析模型中的实体关系图和数据字典进行数据设计,包括数据库设计或数据文件的设计。(6)在设计的基础上,依旧分析模型中的加工规格说明、状态转换图进行过程设计。(7)制定测试计划。结构化设计与结构化分析的关系如图。左面是结构化分析阶段所建立的分析模版
6、,右面为建立的设计模型。图2 结构化设计与结构化分析关系实体- 数据关系图 流图 数据字典状态-迁移图控制规格说明加工规格说明数据对象描述体系结构设计接口设计数据设计过程设计1.3模块结构与数据结构 软件的结构包括两部分,一部分为软件的模块结构,另一部分为软件的数据结构。虽然这两部分是有密切联系的。但是在传统方法中,这两部分的设计是分开进行的。1.3.1模块结构表示 一般通过功能划分过程来完成软件结构设计。功能划分过程从需求分析确立的目标系统的模型出发,对整个问题进行分割,使其每一部分用一个或几个软件模块加以解决。一个软件系统通常由很多模块组成,结构化程序设计的函数和子程序都可称为模块。它是程
7、序语句按逻辑关系建立起来的组合体。对于大的模块,一般还可以继续分为功能独立的较小模块,将不能再分解的模块称为原子模块。通常,可以按照在软件系统中的功能将模块分为四种类型。(1) 传入模块:传入模块的功能是取得数据或输入数据,经过某些处理,再将其传送给其他模块。(2) 传出模块:传出模块的功能是输出数据,在输出之前可能进行某些处理,数据可能被输出到系统的外部,也可能会输出到其他模块进行进一步的处理,但最终的目标是输出到系统的外部。(3) 变换模块:也叫加工模块,从上级调用模块取得数据,进行特定的处理,转换成其他形式,再将加工结果返回给调用模块。(4) 协调模块:协调模块本身一般不对数据进行加工,
8、如数据X和Y,其主要功能是通过调用、协调和管理其他模块来完成特定的功能,如结构化程序设计中的主程序。1.3.2模块结构模块结构表明了程序各个部件的组织情况,通常是树状结构和网状结构。是软件的过程的表示,并没有表明软件的某些过程性特征。(1) 树状结构。位于最上层的的根部是顶层模块,他是程序的主模版。与其联系的有若干下属模块,各下属模块还可以进一步引出更下一层的下属模块。由下图可知,树状结构的特点是:整个结构只有一个顶层模块,上层模块调用下层模块,同一层模块之间不可相互调用。(2) 网状结构。网状结构中,任意的两个模块间都可以有调用关系。不存在上下级模块关系,分不出层次;任何两个模块都是平等的,
9、没有从属关系。ADCBHIGABCEFD图4网状结构图3树状结构1.3.3结构图结构图是精确表达模块结构的图形标识工具,可以清楚的反映软件模块之间的层次调用关系和联系。严格定义了各个模块的名字、功能和接口,集中反映了设计思想。(1) 模块的调用关系接口:在结构图中,两个模块之间用单向箭头连接。箭头从调用模块指向被调用模块,表示调用模块调用了被调用模块。被调用模块执行完成后,控制又返回到调用模块。(2) 模块间的信息传递:当一个模块调用另一个模块时,调用模块把数据或控制信息传送给被调用模块,以使被调用模块能够运行。而被调用模块在执行过程中又把它产生的数据或控制信息送给调用模块。为了表示在模块之间
10、传递的数据或控制信息,在连接模块的箭头旁边给出短箭头,并且用尾端带有空心园的短箭头表示数据信息,用尾端带有实心园的短箭头表示控制信息。(3) 两个辅助符号:如图所示,当模块A有条件的调用另一个模块B时,在模块A的箭头尾部标以一个菱形符号;当一个模块A反复的调用模块C和模块D时,在调用箭头尾部则标一个菱形符号。ABCD图5 条件调用和循环调用的表示(4) 结构图的状态特征。图所表示的是一个软件系统的分层模块结构图。上级模块调用下级模块,他们之间存在着主从关系,同一层模块之间并没有这种主从关系。模块间的连线:模块之间的调用箭头也可用没有箭头方向的直线表示,在用直线表示时,用模块所处的位置表示他们之
11、间的调用关系,位于上面的模块调用位于下面的模块。结构图的深度:在多层次的结构图中,模块结构的层次数称为结构图的深度。结构图的深度在一定程度上反映了程序结构的规模和复杂程度。结构图的宽度:结构图中同一层模块的最大模块数称为结构图的宽度。模块的扇入和扇出:扇出表示一个模块直接调用的下属模块数目,扇入则定义为调用一个给定的模块的调用模块的数目。1.3.4数据结构的表示数据结构是数据的各个元素之间的逻辑关系的一种表示。数据与程序是密不可分的,实现相同的功能,采用的数据结构不同,底层的算法也不相同。数据结构设计应先确定数据的组织、存取方式、相关程度,以及信息的不同处理方法,典型的数据结构种类是有限的。所
12、谓的标量项就是单个的数据元素,如一个布尔量、整数、实数或一个字符串,可以通过名字对他们进行存取。基本数据结构可以构成其他数据结构可以用包含标量项、向量或N维空间的多重链表来建立分层树状结构和网状结构,并实现多种集合的存储。1.4创建良好的设计的原则1.4.1分而治之和模块化 分而治之就是将大型复杂的问题分解为许多容易解决的小问题。模块化是将整体软件划分成独立访问的模块,不同的模块通常是具有不同功能或职责。每个模块可以独立的开发、测试,最后组装成完整的软件。一个模块的规模应该由它的功能和用途决定,并不是分解的越小越好。存在一个模块个数M,使得开发成本达到最小。M总的软件成本连接成本最小成本范围成
13、本/模块模块个数模块数图6 模块大小、模块数目与成本的关系1.4.2 模块独立性 模块独立性是指软件系统中每个模块只涉及软件要求的具体子功能,而和软件系统中其他的模块接口都是简单的。一般采用两个准则度量模块的独立性,即模块间的耦合和模块的内聚。 耦合是模块间的相对独立性的度量,模块之间连接的越紧密,联系越多,耦合性就越高,而模块独立性就越弱。内聚是模块功能强度的度量。一个模块内部各个元素之间的联系越紧密,它的内聚性就越高,相对的,其他模块之间的耦合性就会降低。因此,模块独立性比较强的模块应该是高度内聚、松散耦合的模块。1. 松散耦合耦合性是程序结构中各个模块之间相互关联的度量。取决于各个模块之
14、间的接口复杂程度、调用模块的方式以及哪些信息通过接口。(1) 非直接耦合。两个模块之间没有直接关系,他们之间的联系完全是通过主模块的控制和调用来实现的。模块之间的独立性最强(2) 数据耦合。一个模块访问里一个模块时,彼此之间是通过数据参数来交换输入、输出信息的。(3) 标记耦合。如果一组模块通过参数表达传递记录信息,就是标记耦合。(4) 控制耦合。一个模块通过传送开关,标志,名字等控制信息,明显的控制选择另一个模块的功能。(5) 外部耦合。一组模块都访问同意全局变量而不是同一全局数据结构,而且不是通过参数表传递该全局变量的信息。(6) 公共耦合。一组模块都访问同一个公共数据环境。(7) 内容耦
15、合。一个模块直接访问另一个模块的内部数据。一个模块不通过正常入口转到另一模块内部。两个模块有一部分代码重叠。一个模块有多个入口。2高度内聚 一个内聚程度高的模块应当只完成软件过程中的一个单一的任务,而不与程序其他的部分进程发生关系。(1) 巧合内聚。模块内各部分之间没有联系,或者即使有联系,这种联系也很松散。(2) 逻辑内聚。模块把几种相关功能组合在一起,每次被调用时,由传送给模块的判定参数来确定该模块应该执行哪一种功能。(3) 时间内聚。模块为多功能模块,各个功能的执行与时间有关,通常要求所有功能必须在同一时间段内执行。(4) 过程内聚。一个模块内的处理是相关的,必须以特定程序执行。(5)
16、通信内聚。一个模块内各功能部分都使用了相同的数据,或产生了相同数据。(6) 信息内聚。模块完成多个功能,各个功能都在同一个数据结构上操作,每一项功能都有一个唯一的入口点。(7) 功能内聚。一个模块中各个部分都是完成某一种具体功能必不可缺少的组成部分。1.4.3提高抽象层次 抽象是指忽视一个主题与当前目标无关的那些方面,以便充分的注意与当前目标相关的方面。设计软件时,设计开始时应该尽量提高软件的抽象层次。按抽象级别由高到低进行软件设计。1.4.4复用性设计 复用是指同一实体不做修改或者稍加修改就可以多次重复使用,将复用的思想用于软件开发。复用的范围包括软件开发的各个阶段,包括需求模型和规格说明、
17、设计模型、文档、测试用例的复用。1.4.5灵活性设计 保证软件灵活性的关键是抽象。在设计中引入灵活性的方法如下。(1) 降低耦合并提高内聚。易于提高替换能力。(2) 建立抽象。创建有多态操作的接口和父类。(3) 不要将代码写死。消除代码中的常数。(4) 抛出异常。由操作的调用者处理异常。(5) 使用并创建可复用的代码。1.4.6预防过期 预防过期的规则如下。(1) 避免使用早期发布技术。(2) 避免使用针对特定环境的软件库。(3) 避免使用软件库中文档不全或很少使用的功能。(4) 避免使用小公司提供的可复用构件和特殊硬件。(5) 使用众多厂商支持的标准语言和技术。1.4.7可测试性设计 进行可
18、测试性设计时,坚持以下原则。(1) 坚持测试驱动设计的方法。(2) 函数小型化。尽量做到一个函数一个操作。(3) 数据的显示与控制分离,使修改程序功能而不影响视图变得容易。1.5面向数据流的设计方法 面向数据流的设计方法也称为过程驱动的设计方法,与软件需求分析阶段的结构化分析方法相衔接,可以与编码阶段的“结构化程序设计方法”相适应,成为常用的结构化设计方法。1.5.1设计过程(1)复查并精化数据流图。对需求分析阶段得出的数据流图进行认真复查,并在必要时精化。(2)确定数据流图中数据流的类型。(3)导出初始的软件结构图。根据数据流类型,应用变换型映射方法或事务型映射方法得到初始的软件结构图。(4
19、)逐级分解。需要进行一级分解和二级分解。(5)精化软件结构。使用设计度量和启发式规则对得到软件结构进一步精化。(6)导出接口描述和全局数据结构。对每一个模块,给出进出该模块的信息,即该模块的接口描述。详细设计复读用启发式设计规则精化软件结构导出接口描述和全局数据结构区分事务中心和数据接收通路区分输入和输出分支映射成事务结构映射成变换结构精化数据流图数据流类型图7 基于数据流方法的设计过程1.5.2典型的数据流类型和系统结构 典型的数据流类型有变换型数据流和事务型数据流,数据流的类型不同,得到的系统结构也不同。1. 变换型数据流与交换型系统结构图取得CC变换成D取得AA变换成B取得BB变换成CD
20、变换成E给出EDC主模块给出DCDD图8 变换型的系统结构图2事务型数据流与事务型系统结构图结果结果作业作业已分析的作业内部表示的作业事务中心输入已分析的作业输出结果调 度读入作业分析作业事务1事务2事务3操作1操作2操作3操作4操作5图8 事务性系统结构图1.5.3变换型映射方法 变换型映射方法是一系列设计步骤的总称,将具有变换流特点的数据流图按预先确定的模式映射成软件结构。先运用变换型映射方法建立初始的变换型系统结构图,然后对他做进一步改进,最后得到系统的最终结构图。 变换分析方法分为四步组成:重画数据流图;区分有效输入,有效输出和中心变换部分;进行一级分解,设计上层模版;进行二级分解,设
21、计输入,输出和中心变换部分的中、下层模版。1.5.4事务型映射方法 一种数据流可以引发一个或多个处理,这些处理能够完成该作业要求的功能,这种数据流就叫做事务。事务分析方法的步骤如下。(1) 识别事务源。从问题定义和需求分析的结果中,找出各种需要处理的事务。(2) 规定适当的事务型结构。在确定了该数据流图具有事务型特征之后,根据模块化分理论,建立适当的事务型结构。(3) 识别各种事务和它们定义的操作。(4) 注意利用公共模块。如果不同事务的一些中间模块可由具有累死的语法和语义的若干个低层模块组成,可以把这些模块构造成低级模块。(5) 对每一事务,或对联系密切的一组事务处理模块。(6) 对事务处理
22、模块规定他们全部的下层操作模块。(7) 对操作模块规定他们的全部操作细节。对于大型系统的复杂事务处理,可能有若干层细模块。1.5.5软件模块结构的改进方法(1)模块功能的完善化。一个完整的功能模块,不仅能够完成指定的功能,而且还能告诉使用者完成任务的状态,以及不能完成的原因。(2)消除重复功能,改善软件结构。如果发现几个模块的功能之间有相似之处,可以加以改进。(3)模块的作用范围应在控制范围之内。模块的控制范围包括它本身及其所有的从属模块。(4)尽可能的减少高扇出结构,随着深度增大扇入。(5)避免或减少使用病态连接,限制使用直接病态连接。公共数据域病态连接。通信模块连接。为了避免病态连接,防止
23、内容耦合,设计应尽量达到单入口和单出口,便于阅读程序、理解程序,并且不易出错。(6)模块的大小要适中。1.6接口设计1.6.1接口设计概述 接口设计的依据是数据流图中的自动化系统边界。自动化系统边界将数据流图中的处理划分为手工处理部分和系统处理部分,在系统边界之外的是手工处理部分,在系统边界之内的是系统处理部分。 接口设计主要包括三方面:模块或软件构件间的接口设计;软件与其他软硬件系统指尖的接口设计;软件与用户之间的交互设计。1.6.2人机交互界面 1.用户界面应具有的特征(1)可使用性:使用简单、界面一致、拥有HELP帮助功能、快速的系统影响和和低得系统成本、具有容错能力。(2)灵活性:考虑
24、到用户的特点、能力和知识水平,应当是用户接口满足不同用户的要求。(3)可靠性:用户界面的可靠性是指无故障使用的间隔时间。2.用户类型(1)外行型:从未使用过计算机的系统用户。(2)初学型:尽管对新的系统不熟悉,但对计算机还有一些使用经验的用户。(3)熟练型:对一个系统有相当多的经验的用户,能够熟练操作。(4)专家型:在熟练的基础上,了解内系统部的构造,有关于系统工作机制的专业知识,具有维护和修改基本系统的能力。3.界面设计类型(1)使用的难易程度:对于没有经验的用户,该界面使用的难度有多大。(2)学习的难易程度:学习该界面的命令和功能的难度有多大。(3)操作速度:在完成一个制定的操作时,该界面在操作步骤、击键和反映的时间等方面效率有多高。(4)复杂程度:该界面提供了什么功能,能否用新的方式组合这些功能以增强界面的功能。(5)控制:人机交互时,是由计算机还是人发起控制对话。(6)开发的难易程度:设计该界面是否有困难,开发工作量有多大。4设计详细的交互(1)一致性。采用一致的术语、一致的步骤和一致的活动。(2)操作步骤少。(3)每当用户完成系统的一个动作时,有反馈信息。(4)提供Undo功能。(5)减少人脑的记忆负担。(6)提高学习效率。1.7数据设计 数据是软件系统中的重要组成部分,在设计阶段必须对要存储的数据及其结构进行设计。