第4章 结构化设计方法范文
- 格式:doc
- 大小:186.00 KB
- 文档页数:11
结构化设计方法1.结构化设计方法的特点结构化设计方法简称SD方法,是系统设计时应用最为广泛和最为成熟的方法之一。
一般来说,SD方法是继SA方法之后,将结构化分析阶段形成的系统逻辑冒险转化成一个具体的物理方案,该阶段主要是解决“如何做”的问题。
在这一阶段中,系统设计人员的主要任务是在保证逻辑模型的前提下,尽可能提高系统的可靠性、工作质量、效率和可变更性。
SD方法分为总体设计和详细设计两步。
总体设计的任务是决定系统的模块结构,这一步主要考虑以下四个问题:如何将系统划分为一个个模块;模块之间传递什么数据;模块之间如何进行调用;如何评价模块结构的质量。
详细设计的任务是具体考虑每一个模块内部采用什么算法,模块的输入、输出以及该模块的功能。
2. 结构图SD方法的主要生成文档是结构图以及相应的模块能够说明。
结构图简称SC图。
结构图的基本元素是模块,一般用矩形框表示。
结构图将一个系统分解为若干个模块,每个模块可以看成一个“黑盒”,在图中表示它的层次、构成和相互之间的关系。
结构图通常用层次结构表示,这样的结构可以描述系统逐层分解的过程,即系统总的功能是如何分解为一个个具体任务的。
由于结构图是一个分层结构,因此,图中的上层模块与下层模块的关系旧丛逻辑上讲是模块的能够包括了下层模块的功能,从物理上讲是一个调用关系。
一般来说,结构图以下四种成分。
(1)模块模块用矩形框表示,矩形框中表明模块的名称,它反映模块的功能。
在结构图中,模块被看成是一个黑盒,只考虑该模块的外部表现(如输入/输出参数和功能),而不考虑该模块的内部机构(如内部代码,内部数据等)。
(2)调用在结构图中,用一些带有圆圈的小箭头来表示模块之间的通信,即模块调用时数据或控制信息的传递,箭头的方向表示传递的方向。
其中带有空心圆圈的小箭头表示数据的传递,而带有实心圆圈的小箭头表示控制信息的传递。
(3)模块间信息传递在结构图中,有时还要用到一些辅助符号。
用带箭头的连线表示模块之间的通信,箭头的方向表示传递的方向。
第四章结构化程序设计的三种结构4.1 顺序结构程序设计一、结构化程序设计的程序结构顺序结构、分支结构/选择结构、循环结构二、C语言语句1、9种控制语句2、表达式语句3、特殊语句三、格式化输出--printf()函数printf()函数的作用:向计算机系统默认的输出设备(一般指终端或显示器)输出一个或多个任意类型的数据。
printf()函数的一般格式printf("格式字符串" [,输出项表]);1、"格式字符串"也称"转换控制字符串",可以包含三种字符(1)格式指示符。
格式指示符的一般形式如下:%[标志][宽度][.精度][F|N|h|L][类型]常用的标志字符如表3-1所示,常用的宽度指示符如表3-2所示,常用的精度指示符如表3-3所示,长度修饰符如表3-4所示,类型转换字符如表3-5所示。
(2)转义字符'\n'就是转义字符,输出时产生一个"换行"操作。
转义字符通常起控制作用(3)普通字符──除格式指示符和转义字符之外的其它字符。
格式字符串中的普通字符,原样输出。
例如printf("radius=%f\n", radius);语句中的"radius="是普通字符。
2.输出项表输出项表是可选的。
如果要输出的数据不止1个,相邻2个之间用逗号分开。
下面的printf()函数都是合法的:(1)printf("I am a student.\n");(2)printf("%d",3+2);(3)printf("a=%f b=%5d\n", a, a+3);必须强调:"格式字符串"中的格式指示符,必须与"输出项表"中、输出项的数据类型一致,否则会引起输出错误3、格式指示符输出不同类型的数据,要使用不同的类型转换字符。
第4章 结构化设计方法 4.1 当你“编写”程序时你设计软件吗?软件设计和编码有什么不同吗? 在“编写”程序时并没有设计软件。软件设计包括概要设计和详细设计,编码是将详细设计中的过程描述转换成用程序设计语言来描述。 4.2 举出3个数据抽象的例子和可以用来操作这些数据抽象的过程抽象的一个例子。 抽象是忽略事物的细节,获取其本质特征的过程。抽象是一种重要的机制,使人们能够对复杂系统能够很好地理解、交流和推理。在软件领域,可以将抽象分为两类,即数据抽象和过程抽象。 在传统的结构化程序设计语言中,就提供了这两种抽象机制。 (1) 数据抽象:在所有的结构化程序设计语言中,用户都可以自定义抽象数据类型。如定义抽象数据类型Student(学生)、Course(课程)、ClassScoreList(班级成绩单)。 (2) 过程抽象:过程抽象也称为是基于方法的抽象。过程抽象使我们关心处理过程的名字和它能做什么,而无需知道如何完成所有实现细节。如求班级总平均分average(ClassScoreList)就是一个过程抽象。 在面向对象的程序设计语言中,抽象与封装的概念密切相关,数据抽象和相关的过程抽象被封装在类中,不同类中相似的过程抽象(方法)又可以进一步抽象,放在接口中。封装是保证事物有明确内外界限的机制。内部是受保护的,与外部事物相隔离。 4.3 应在什么时候把模块设计实现为单块集成软件?如何实现?性能是实现单块集成软件的唯一理由吗? 由于模块之间的调用降低了系统的运行速度,可能会导致满足不了用户的性能要求,这时就需要将软件设计为单块集成软件。但是在设计时,最好按照模块化的原则进行设计,只是没有显式的模块定义而已。这样的程序也具有模块化的优点。性能是实现单块集成软件的唯一理由。 4.4 是否存在一种情况:复杂问题需要较少的工作去解决?这样的情况对模块化观点有什么影响? 通过对复杂的问题进行合理分解,分解为若干个相对简单及独立的子问题,就可以用较少的工作去解决。这种情况能够较好地支持模块化的观点,每个子问题用单独的模块去解决,模块之间应该是高内聚、低耦合的,这样才能减少工作量,否则,虽然每个模块的工作简单了,但模块之间的联系很复杂,也增加了问题解决的难度和工作量。 4.5 使用数据流程图和处理叙述,描述一个具有明显事务流特性的计算机系统。使用本章所介绍的技术定义数据流的边界,并将DFD映射成软件结构。 略。 4.6 一些设计人员认为所有的数据流都可以当做是变换流。试讨论当事务流被当成变换流时,会对导出的软件体系结构有什么影响。请使用例子来说明要点。 当事务流被当成变换流时,首先按变换流导出软件结构,之后再将位于中间的“变换模块”替换成事物中心。所不同的是,其输入数据不是来自下属的输入模块,而是从最顶层的主控模块传入的,输出数据也是传给主控模块,之后再由主控模块传给输出模块。这样会增加模块层次及数据的传送次数。 例如,对于下面的事务型数据流,如果按照事务型数据流进行处理,得到的初始模块结构如右图所示。
事务型数据流 按事务型得到的软件结构 如果按变换型处理,得到的初始结构图如下图所示。
初始结构图 再对中间部分进一步分解,得到下面的结构图。
主模块 输出模块 输入模块 变换模块 第4章 习题与思考题参考答案
3 如果想缩短数据传递的路径,就需要对上图进行改进,可以将“调度”模块合到“事务中心”模块中。 4.7 什么是持久的数据源? 对于应用系统来说,持久的数据源是指应用系统关闭再重新启动后,关闭之前的数据依然存在。这些数据一般要存储在文件或数据库中。 4.8 用面向数据流的方法设计第3章习题3.4所描述的银行存款业务的软件结构,并使用改进方法对模块结构进行精化。 (1) 对第3章习题3.4给出的数据流图进行精化,确定其边界,如下图所示。 (2) 对上图按事务型数据流进行处理,完成第一级分解,得到顶层和一层模块结构图。 第一级分解后的结构图 (3) 完成第二级分解。对上图所示的“输入数据”、“输出数据”和“调度”模块进行分解,得到未经精化的输入结构、输出结构和事务结构。
未经精化的输入结构 未经精化的输出结构
存款业务 输入数据 调度 输出数据
输入数据 输入事务 输入密码
输出数据 打印存款单 打印开户单
调度 处理存款 处理开户 记录存款信息 记录开户信息 记录密码 第4章 习题与思考题参考答案 5 未经精化的事务结构 将上面的三部分合在一起,得到初始的软件结构,如下图所示。
初始软件结构图 (4) 对软件结构进行精化。 1) 由于调度模块下只有两种事务,因此,可以将调度模块合并到上级模块中,如图所示。
将调度模块合并到上级模块后的软件结构 2) “记录密码”模块的作用范围不在其控制范围之内(即“输入密码”模块不在“记
录密码”模块的控制范围之内),需对其进行调整,如图所示。
存款业务 输入数据 调度 输出数据
输入事务 输入密码 打印存款单 打印开户单 处理存款 处理开户
记录存款信息 记录开户信息 记录密码
存款业务 输入数据 输出数据 输入事务 输入密码 打印存款单 打印开户单 处理存款 处理开户 记录存款信息 记录开户信息 记录密码
存款业务 输入事务 输出数据 输入密码 打印存款单 打印开户单 处理存款 处理开户 记录存款信息 记录开户信息 记录密码 3) 提高模块独立性,对模块结构进行调整,如下图所示。 调整后的模块结构图 4.9 将大的软件划分成模块有什么好处?是不是模块划分得越小越好?划分模块的依据是什么? 将大的软件划分成独立命名且可独立访问的模块,不同的模块通常具有不同的功能或职责。这种方法有利于将复杂的问题简单化,是分而治之策略的具体表现。 尽管模块分解可以简化要解决的问题,但模块分解并不是越小越好。当模块数目增加时,每个模块的规模将减小,开发单个模块的成本确实减少了;但是,随着模块数目增加,模块之间关系的复杂程度也会增加,设计模块间接口所需要的工作量也将增加。 划分模块的依据是,模块只具有单一的功能且与其他模块没有太多的联系。 4.10 什么叫“自顶向下、逐步细化”? 自顶向下、逐步细化的设计过程,主要包括两个方面:一是将复杂问题的解法分解和细化成由若干个模块组成的层次结构;二是将每个模块的功能逐步分解细化为一系列的处理。 在处理较大的复杂任务时,常采取“模块化”的方法,即在程序设计时不是将全部内容都放在同一个模块中,而是分成若干个模块,每个模块实现一个功能。划分模块的过程可以使用自顶向下的方法实现。 模块分解完成后,下一步的任务就是将每个模块的功能逐步分解细化为一系列的处理。这个过程是对问题求解,并由抽象逐步具体化的过程。使用这种方法便于检查程序的正确性。在每一步细化之前,应仔细检查当前的设计是否正确。如果每一步细化、设计都没有问题,则整个程序的算法是正确的。由于每一次向下细化都不太复杂,因此容易保证整个算法的正确性。
存款业务 输入事务 输入密码 打印存款单 打印开户单 处理存款 处理开户 记录存款信息 记录开户信息 记录密码 第4章 习题与思考题参考答案
7 4.11 结构化程序设计禁止使用goto语句吗?如果程序中使用了goto语句,是否就可以断定它是非结构化的? 结构化程序设计并不禁止使用goto语句。如果程序中使用了goto语句,并不能断定它是非结构化的。 4.12 对于给定的算法,如何判断它是否是结构化的? 对于给定的算法,如果符合以下三条原则,就可以判断它是结构化的。 (1) 使用语言中的顺序、选择、重复等有限的基本控制结构表示程序逻辑。 (2) 选用的控制结构只准许有一个入口和一个出口。 (3) 程序语句组成容易识别的块(Block),每块只有一个入口和一个出口。
4.13 对于图4-49所示的流程图,试分别用N-S图和PAD表示之。
图4-49 流程图 对应的N-S图如下: 对应的PAD如下:
4.14 图4-50所示的流程图完成的功能是使用二分查找方法在table数组中找出值为item的数是否存在。
(1) 判断此算法是否是结构化的,说明理由。 (2) 若算法是非结构化的,设计一个等价的结构化算法,并用N-S图表示。
F START A B Q
END
T F
T P
while P A B until !Q
while P A until !Q B 图4-50 二分查找算法的流程图 (1) 不是结构化的,最上面的循环有两个出口,最下面的分支有三个入口。
F F F
T F
F
table(i)>item (finish-start)>1 table(start)=item table(finish)=item flag=0 flag=1
i=(start+finish)/2 table(i)=item table(I)
finish=i-1 start=i+1
T T
T
F T T
开始
结束