第4章 软件概要设计
学习本章,我们要考虑以下几个问题:
软件概要设计指的是什么?
软件概要设计要做的事情是什么?
用什么来评价软件设计的技术质量?
软件结构优化的准则是什么?
如何进行软件概要设计?
以上问题就是本章所要讨论的内容。
一、软件概要设计指的是什么?
我们知道,软件设计是把一个软件需求转换为软件表示的过程,而概要设计(又称结构设计)就是软件设计最初形成的一个表示(这里的表示是一个名词),它描述了软件的总的体系结构。简单地说软件概要设计就是设计出软件的总体结构框架。而后对结构的进一步细化的设计就是软件的详细设计或过程设计。本章所学内容主要就是软件的概要设计内容。
二、软件概要设计的基本任务
软件概要设计阶段要做的事情是什么呢? 总的来看有四个方面:它们是
1、设计软件系统结构(软件结构)
2、数据结构及数据库设计
3、编写概要设计文档
4、评审
在需求分析阶段,已经把系统分解成层次结构,而在概要设计阶段,需要进一步分解,划分为模块以及模块的层次结构。划分的具体过程是:
(1)采用某种设计方法,将一个复杂的系统按功能划分成模块。
(2)确定每个模块的功能。
(3)确定模块之间的调用关系。
(4)确定模块之间的接口,即模块之间传递的信息。
(5)评价模块结构的质量。
对于大型数据处理的软件系统,还要对数据结构及数据库进行设计。
在概要设计阶段,还要编写概要设计文档,我们初学者有一个不是很好的做法,就是在编程序时,往往不注意文档的编写,导致以后软件修改和升级很不方便,用户使用时也得不到帮助。所以应该在软件设计的每个阶段编写相应文档,在概要设计阶段,主要有以下文档需要编写:
(1)概要设计说明书。
(2)数据库设计说明书。
(3)用户手册,
(4)修订测试计划。
最后一个任务就是评审,在概要设计中,对设计部分是否完整地实现了需求中规定的功能、性能等要求,设计方案的可行性,关键的处理及内外部接口定义正确性、有效性,各部分之间的一致性等都要进行评审,以免在以后的设计中发现大的问题而返工。
以上就是软件概要设计的四个基本任务,总结一下用八个字表示:两类结构文档评审。(两类结构就是指软件结构和数据结构及数据库设计)
在了解了软件概要设计的基本任务之后,我们来看看软件设计的基本原理,也就是用于衡量软件设计的技术质量的一些标准。
三、软件设计的基本原理
1、模块化
模块就是指在程序中的数据说明、可执行语句等程序对象的集合,或者是单独命名和编址的元素。如高级语言中的过程,函数、子程序等。每个模块可以完成一个特定的子功能,各个模块可以按一定方法组装起来成为一个整体。从而实现整个系统的功能。
模块化就是指解决一个复杂问题时自顶向下逐层把软件系统划分成若干模块的过程。
为了解决复杂的问题,在软件设计中就必须把整个问题进行分解来降低复杂性,这样就可以减少开发工作量并降低开发成本和提高软件生产率。但是划分模块并不是越多越好,因为这会增加模块之间接口的工作量。所以划分模块的层次和数量应该避免过多或过少。
2、抽象
抽象这个词本身也比较抽象,(老师要小明用抽象和具体造一个句子,可是他不懂,就问妈妈,什么是抽象,什么是具体? 妈妈告诉他:抽象就是看不见摸不着的,具体就是看得见摸得着的。小明懂了,很快造好了一个句子,是这样的:今天我很早起床,看见具体的妈妈在炒具体的菜,我打开窗户,抽象的新鲜空气呼地一下跑进来,真舒服啊。)呵呵,事实上,抽象并不是这么简单的意思,它是一种思维工具,就是把事物本质的共同特性抽出来而不考虑其他细节,比如说我们可以把把男人女人老人小孩的共同本质特性抽出来之后形成一个概念"人",这个概念就是抽象的结果。在软件工程中就是这样,在每个阶段中,抽象的层次逐步降低,在软件结构设计中的模块分层也是由抽象到具体的分析和构造出来的。比如上一层的模块所进行的加工是一个抽象的操作"销售统计",分解到最后一层,就可能是具体"打印报表"的操作了。
3、信息隐蔽
信息隐蔽的意思就是指,在设计和确定模块时,使得一个模块内包含的信息(过程或数据),对于不需要这些信息的其他模块来说是不能访问的。举个例子吧,假设我是程序中的一个模块,电话机是另一个模块,我在使用电话机时,对电话机的控制是通过几个按键来确定的,输入的数据是我的语音,输出的数据是对方的语音,而这些输入、输出的数据变换以及控制在电话机内部是怎么实现的我不需要知道,同时也不能加以直接控制,这样,如果电话机坏了,修复或更换后对我的使用是没有任何影响的。所以说,电话机这个模块的信息隐蔽是十分完善的。在软件设计中,模块的划分也要采取措施使它实现信息隐蔽。
4、模块独立性
模块独立性是指每个模块只完成系统要求的独立的子功能,并且与其他模块的联系最少且接口简单。这个概念就是上面说的三个基本原理的直接产物,在概要设计过程中,就是要求设计出具有良好模块独立性的软件结构。
那么如何来衡量软件的模块独立性呢?这里有两个定性的度量标准。
(1)耦合性:就是指模块之间的联系紧密程度。模块之间联系越紧密,其耦合性越强,独立性就越差。
模块的耦合性从低到高可分为以下几种类型:(假设某人为一模块)
无直接耦合 (比如陌生人之间的联系)
数据耦合 (比如去售货员与顾客之间的联系)
标记耦合 (比如两个人下棋)
控制耦合 (领导和下属之间的联系)
公共耦合 (比如图书馆的所有借书者之间的联系)
内容耦合 (比如小两口之间的联系)
在软件设计中,提高模块的独立性,建立模块间尽可能松散的系统,是模块化设计的目标。为了降低模块间的耦合度,可以采取以下措施:
(1)在耦合方式上降低模块间接口的复杂性。
(2)在传递信息类型上尽量采用数据耦合,避免使用控制耦合,慎用或有控制地使用公共耦合。在实践中要根据实际情况综合考虑。
2、内聚性
内聚性是指模块内部各个元素彼此结合的紧密程度。根据内聚性的从低到高可分为以下六种类型:
偶然内聚:指一个模块内的各处理元素之间没有任何联系。(公共汽车内的人群)
逻辑内聚:指模块内执行几个逻辑上相似的功能,通过参数确定该模块完成哪一个功能。(警察局里的警察)
时间内聚:把需要同时执行的动作组合在一起形成的模块为时间内聚模块。(交响乐团的演奏员)
通信内聚:指模块内所有处理元素都在同一个数据结构上的操作。或者指各处理使用相同的输入数据或者产生相同的输出数据。(建筑工地上的工人)
顺序内聚:指一个模块中各个处理元素都密切相关于同一功能且必须顺序执行,前一功能的元素的输出就是下一功能元素的输入。(我们可以想像纺织厂中从纺纱到织布的各个操作形成的一个模块,就是一种顺序内聚)
功能内聚:这是最强的内聚,指模块内所有元素共同完成一个功能,缺一不可,模块已不可再分。(就如两个人演狮子舞,要完成狮子形象的再现,两个人缺一不可.)
耦合性与内聚性是模块独立性的两个定性标准,将软件系统划分模块时,尽量做到高内聚,低耦合,提高模块的独立性。在内聚性与耦合性发生矛盾的时候,最好优先考虑耦合性,也就是先保证耦合性低一些。
四、软件结构的优化准则
首先应学会用图形表示软件结构,软件结构图反映了整个系统的功能实现,即将来编好程序中的控制层次体系。软件结构往往用树状或网状结构的图形来表示。
请大家对照课本的解释来看软件结构图包括哪些内容。
我们已经知道了软件概要设计的主要任务就是软件结构的设计,为了提高设计的质量,可以根据下面的设计优化准则进行优化:在这些准则中,都是针对模块及模块间关系来提出的。
1、模块的划分:要做到高内聚,低耦合,保持相对独立性。
2、模块的控制:模块的作用范围要在他的控制范围内,判定所在的模块应与受其影响的模块在层次上尽量靠近)
3、形成的结构;软件结构的深度、宽度、扇出、扇入要适当
4、模块的大小: 要适中。
5、模块的接口:模块的接口要简单、清晰、含义明确,便于理解、易于实现、测试与维护)。
五、概要设计的设计方法。
(一)面向数据流的设计方法(这是需要我们熟练掌握的方法)
面向数据流的设计方法是以需求阶段产生的数据流图为基础,按一定的步骤映射成软件结构,因此又称为结构化设计(Structured Design SD)。这是目前使用最广泛的软件设计方法之一,应该熟练掌握它。
1、首先要研究数据流图(DFD)的类型,无论何种软件系统,DFD一般都可分为变换型和事务型两类。(课本第51页)
先来看变换型数据流图,顾名思义,变换就是把输入的数据处理后变成另外的数据输出,所以变换型数据的工作过程就是三步:取得数据、变换数据和输出数据。在图4-6中,可以看到两股数据流经过交换中心变成一股数据流进行输出。虚线为标出的流界。
再来看事务型数据流图,所谓事务也是一个处理,但不是数据变换,而是将输入数据流分离成许多发散的数据流,形成许多加工路径,并根据值选择其中一个路径来执行。举个例子,好比有一个邮件分发中心,把收进的邮件根据其发送地址进行分流,有的用飞机邮送,有的用汽车来运输等等。
在大型软件系统中的DFD数据流图中,这两种类型特征都有可能存在。
2、SD方法设计过程
1)精化DFD。
2)确定DFD类型并进行相应的映射。
3)分解上层模块,设计中下层模块结构
4)根据优化准则对软件结构求精。
5)描述模块功能、接口及全局数据结构
6)复查,如果有错则转向2)修改完善,否则进入详细设计。
下面我们通过例子来说明变换分析设计和事务分析设计方法。
3、变换分析设计
以课本53页图4-8为例说明变换分析设计。
根据面向数据流的设计方法,第一步是精化DFD,也就是研究分析这个数据流图,我们可以看到图中从A到H的数据流向和加工,图形比较简单。
第二步是确定DFD类型并确定加工中心,在这里已经说明为本图为变换型,在实际分析中应该根据每个相关操作来确定其类型。在图中,我们可以直观地看到中间几股数据流的汇合处是系统的变换中心。也可以通过双向寻找法来确定,左边是物理输入端,从f1沿着单向路径一直到f3,后面的f4是从C流出的,同时C还有f5流出,则可见f4,f5不能再看作是系统的输入,因此可确定f4,f5前一个数据流f3就是系统的逻辑输入,同样,我们从右边的物理输出端往左边沿数据流的反向寻找,可以发现f4,f6不能看作是整个系统的输出,因此可以确定f7,f8是逻辑输出端,然后在这两个分界处添上虚线,这样,DFD的三部份就确定了。
第三步 设计软件结构的顶层和第一层,根据变换中心可以对应得到主模块的位置,就可以画出顶层模块(即主模块,在实际应用中,这个模块的名字就是系统的名字,如销售管理系统等)。然后在这个模块下方根据划分好的三个部分画出三个功能模块,即输入、变换和输出模块,就是图中的get f3,将f3变换成f7和f8模块,put f7及put f8模块,注意,这里应当为每个输入和输出设计一个模块。然后将这些模块与顶层模块用连线连上表示所属控制。画上相应的数据传送箭头。
第四步 分解上层模块,设计中下层模块。 根据上面的方法,分解输入模块,图中的get f3模块的功能是向主模块提供数据,而在DFD中可以看到f3是数据流f2经过B操作后流出的,因此这里有两个部分,就是接收f2数据,再通过B转换流出。所以在get f3模块下画出两个子模块 get f2 和B操作模块。
就这样一一分解,可以画出所有的输入和输出子模块,直到物理输入和输出为止。
对于变换中心的下属模块,根据数据流和变换操作,以每个基本加工建立一个功能模块,可以画出CDE三个子模块。
整个过程并不复杂,画好后根据实际情况对软件结构进行优化,也就是进行必要的合并或分解。以求设计出高内聚低耦合的模块组成的、具有良好特性的软件结构。
4、事务分析设计,可以参见图4-9为例。其设计方法大同小异,首先确定DFD类型,这里已指明是事务型,然后找出DFD中的事务中心和加式路径。当DFD中时不要弄错,然后在分解子模块时在调度模块上加一个菱形符号表示判断处理。
5、综合型数据流图与分层数据流图映射成软件结构的设计
有了上面的基础,对综合型的数据流图也可以一一分开来进行设计了。
6、设计后的处理,在软件结构形成之后,我们知道,概要设计的基本任务还有文档的编写,在这个阶段就是要编写一些文档,包括:
(1)为每个模块写一份处理说明
(2)为每个模块提供一份接口说明
(3)数据结构说明
(4)给出设计约束或限制
(5)进行概要评审
(6)设计优化。
本节介绍的设计方法是本章的重点,要求熟练掌握。
(二)基于IDEF0图的设计方法
(三)表示软件结构图的另一种图形工具--HIPO图。
HIPO图清晰易读,主要用于编写概要设计文档中的说明。
本章小结:根据上面的学习,我们可以知道,软件概要设计的四个主要任务,知道评价软件结构设计质量的原理和两个标准即软件模块的耦合性及内聚性,根据这些原理提出了软件结构设计的优化准则,并且详细学习了软件结构的面向数据流图的设计方法。
【编辑推荐】