第5章 总体设计

总体分析总括

总体设计的基本目的:系统应该如何实现?
总体设计=概要设计=初步设计
总体设计的任务:

  1. 划分出组成系统的物理元素:程序,文件,数据库,人工过程和文档。
  2. 设计软件的结构,确定系统每个程序都是由哪些模块组成的,以及这些模块相互间的关系。

总体设计过程:

寻找实现目标系统的各种不同方法
从供选择的方案中选取若干合理的方案
为每个合理方案准备一份系统流程图
物理元素成本效益
制定实现方案的进度计划
选择一个最佳方案向用户和使用部门负责人推荐

5.1 设计过程

确定系统的具体实现方案
确定软件结构
总体设计
系统设计阶段
结构设计阶段

系统设计阶段:确定系统的具体实现方案

1. 设想供选择的方案

需求分析得到的数据流图是总体设计的极好的出发点。

2. 选取合理的方案

通常至少选择低成本、中等成本和高成本的3种方案。
对于每一个合理的方案,分析员应该准备下列4份资料:

  1. 系统流程图
  2. 组成系统的物理元素清单
  3. 成本效益分析
  4. 实现这个系统的进度计划

3. 推荐最佳方案

推荐一个最佳方案,并且制定详细的实现计划。
用户和有关专家认真审查分析员推荐的最佳系统,满足后,进入结构设计

结构设计阶段:确定软件结构

4. 功能分解

结构设计(总体设计阶段任务)

结构设计:确定程序由哪些模块组成,以及这些模块之间的关系。

过程设计(详细设计阶段任务)

过程设计:确定每个模块的处理过程。

功能分析

为确定软件结构,需要从实现角度对复杂的功能进一步分解。

5. 设计软件结构

  1. 一个模块完成一个适当的子功能模块组织成良好的层次系统,顶层模块调用下层模块以实现程序的完整功能。每个下层模块调用更下层模块完成程序的子功能,最下层的模块完成最具体的任务。
  2. 如果数据流图已经细化到适当的层次,则可以直接从数据流图映射出软件结构。

软件结构(模块组成的层次系统)

数据流图映射出软件结构)

6. 设计数据库

对于需要使用数据库的那些系统,软件工程师应该在需求分析阶段所确定系统需求的基础上进一步设计数据库。

7. 指定测试计划

测试部分

8. 书写文档

系统说明

  1. 系统流程图描绘的系统构成方案
  2. 组成系统的物理元素清单
  3. 成本/效益分析
  4. 对最佳方案的概括描述
  5. 精化的数据流图
  6. 层次图或结构图描绘的软件结构
  7. IPO图或其他工具描绘各个模块的算法
  8. 模块间的接口关系
  9. 需求、功能和模块三者之间的交叉参照关系

1-4 选取合理方案后,每个方案的具备条件

用户说明

测试计划

详细的实现计划

数据库设计结果

9. 审查和复审

技术审查–>管理复审

5.2 设计原理

软件设计过程中应该遵循的基本原理和相关概念。

5.2.1 模块化

**模块:**是由边界元素限定的相邻程序元素的序列,而且有一个总体标识符代表它。
**模块化:**就是把程序划分成独立命名且可独立访问的模块,每个模块完成一个子功能,把这些模块集成起来构成一个整体,可以完成指定的功能满足用户的需求。

为什么要模块化?
答:

  • 模块化是为了使一个复杂的大型程序能被人的智力所管理,软件应该具备的惟一属性。
  • 如果一个大型程序仅由一个模块组成,它将很难被人所理解。

在这里插入图片描述
同时考虑模块-接口问题
在这里插入图片描述

模块化的作用:

  • 使软件结构清晰,不仅容易设计也容易阅读和理解。
  • 模块化使软件容易测试和调试,因而有助于提高软件的可靠性。
  • 模块化能够提高软件的可修改性。
  • 模块化也有助于软件开发工程的组织管理。

5.2.2 抽象

**抽象:**现实世界中一定事物、状态或过程之间总存在着某些相似的方面(共性)。把这些相似的方面集中和概括起来,暂时忽略它们之间的差异,这就是抽象。

抽象就是抽出事物本质特性而暂时不考虑细节。

一般抽象过程:

概述的方式叙述问题的解法
面向问题的术语与面向实现的术语结合叙述问题
直接实现的方式叙述问题
最高抽象层次
较低抽象层次
最低抽象层次
落实

5.2.3 逐步求精

**逐步求精:**为了能集中精力解决主要问题而尽量推迟对问题细节的考虑。逐步求精是人类解决复杂问题时采用的基本方法,也是许多软件工程技术的基础。

作用:

  • 它能帮助软件工程师把精力集中在与当前开发阶段最相关的那些方面上,而忽略那些对整体解决方案来说虽然是必要的,然而目前还不需要考虑的细节。
  • 逐步求精方法确保每个问题都将被解决,而且每个问题都将在适当的时候被解决,但是,在任何时候一个人都不需要同时处理7个以上知识块。

5.2.4 信息隐藏和局部化

**信息隐藏:**应该这样设计和确定模块,使得一个模块内包含的信息(过程和数据)对于不需要这些信息的模块来说,是不能访问的。
**信息隐藏:**局部化的概念和信息隐藏概念是密切相关的。所谓局部化是指把一些关系密切的软件元素物理地放得彼此靠近。显然,局部化有助于实现信息隐藏。

5.2.5 模块独立

**模块独立:**模块独立的概念是模块化、抽象、信息隐藏和局部化概念的直接结果。希望这样设计软件结构,使得每个模块完成一个相对独立的特定子功能,并且和其他模块之间的关系很简单。

模块独立的重要性:

  • 有效的模块化(即具有独立的模块)的软件比较容易开发出来。这是由于能够分割功能而且接口可以简化,当许多人分工合作开发同一个软件时,这个优点尤其重要。
  • 独立的模块比较容易测试和维护。这是因为相对说来,修改设计和程序需要的工作量比较小,错误传播范围小,需要扩充功能时能够“插入”模块。

耦合和内聚

模块独立程度的两个定性标准度量:

耦合衡量不同模块彼此间互相依赖(连接)的紧密程度。

耦合要低,即每个模块和其他模块之间的关系要简单;

内聚衡量一个模块内部各个元素彼此结合的紧密程度。

内聚要高,每个模块完成一个相对独立的特定子功能。

模块因素概念要求影响
耦合是对一个软件结构内不同模块之间互连程度的度量在软件设计中应该追求尽可能松散耦合的系统模块间的耦合程度强烈影响系统的可理解性、可测试性、可靠性和可维护性
内聚标志一个模块内各个元素彼此结合的紧密程度,它是信息隐藏和局部化概念的自然扩展1.设计时应该力求做到高内聚;2.中等程度的内聚也是可以采用的(效果同高内聚);3.低内聚不要使用。内聚和耦合是密切相关的,模块内的高内聚往往意味着模块间的松耦合。实践表明内聚更重要,应该把更多注意力集中到提高模块的内聚程度上。

耦合

聚合类型解释
非直接耦合/完全独立如果两个模块中的每一个都能独立地工作而不需要另一个模块的存在,那么它们完全独立。
数据耦合如果两个模块彼此间通过参数交换信息,而且交换的信息仅仅是数据,那么这种耦合称为数据耦合
控制耦合如果两个模块彼此间传递的信息中有控制信息,这种耦合称为控制耦合
特征耦合当把整个数据结构作为参数传递而被调用的模块只需要使用其中一部分数据元素时,就出现了特征耦合
公共环境耦合当两个或多个模块通过一个公共数据环境相互作用时,它们之间的耦合称为公共环境耦合。公共环境可以是全程变量、共享的通信区、内存的公共覆盖区、任何存储介质上的文件、物理设备等等
内容耦合最高程度的耦合是内容耦合。如果出现下列情况之一,两个模块间就发生了内容耦合

附:

在这里插入图片描述
在这里插入图片描述

采取原则:

  1. 尽量使用数据耦合,
  2. 少用控制耦合和特征耦合,
  3. 限制公共环境耦合的范围,
  4. 完全不用内容耦合。

内聚

内聚解释
偶然内聚—低内聚如果一个模块完成一组任务,这些任务彼此间即使有关系,关系也是很松散的,就称为偶然内聚
逻辑内聚—低内聚如果一个模块完成的任务在逻辑上属于相同或相似的一类,则称为逻辑内聚
时间内聚—低内聚如果一个模块包含的任务必须在同一段时间内执行,就称为时间内聚
过程内聚如果一个模块内的处理元素是相关的,而且必须以特定次序执行,则称为过程内聚
通信内聚如果模块中所有元素都使用同一个输入数据和(或)产生同一个输出数据,则称为通信内聚。即在同一个数据结构上操作
顺序内聚如果一个模块内的处理元素和同一个功能密切相关,而且这些处理必须顺序执行,则称为顺序内聚
功能内聚如果模块内所有处理元素属于一个整体,完成一个单一的功能,则称为功能内聚。功能内聚是最高程度的内聚

在这里插入图片描述

5.3 启发规则

1. 改进软件结构提高模块独立性

通过模块分解或合并,降低耦合提高内聚。两个方面:
➢模块功能完善化。一个完整的模块包含:
执行规定的功能的部分
出错处理的部分
返回一个“结束标志”
➢消除重复功能,改善软件结构。
完全相似
局部相似

2. 模块规模应该适中

➢ 经验表明,一个模块的规模不应过大,最好能写在一页纸内。通常规定50~100
行语句,最多不超过500行。数字只能作为参考,根本问题是要保证模块的独立性。
➢ 过大的模块往往是由于分解不充分,但是进一步分解必须符合问题结构,一般
说来,分解后不应该降低模块独立性。
➢ 过小的模块开销大于有效操作,而且模块数目过多将使系统接口复杂。

3. 深度,宽度,扇入,扇出都应适当

• 深度:软件结构中控制的层数,它往往能粗略地标志一个系统的大小和复杂程度。
• 宽度:软件结构内同一个层次上的模块总数的最大值。
• 扇出:一个模块直接控制(调用)的模块数目。
• 扇入:有多少个上级模块直接调用它。
在这里插入图片描述
在这里插入图片描述

4. 模块的作用域应该在控制域之内

• 模块的作用域:定义为受该模块内一个判定影响的所有模块的集合。
• 模块的控制域:是这个模块本身以及所有直接或间接从属于它的模块的集合。
• 在一个设计得很好的系统中,所有受判定影响的模块应该都从属于做出判定的那个模块,最好局限于做出判定的那个模块本身及它的直属下级模块。
在这里插入图片描述
在这里插入图片描述

5. 力争降低模块接口的复杂程度

• 模块接口复杂是软件发生错误的一个主要原因。应该仔细设计模块接
口,使得信息传递简单并且和模块的功能一致。

6. 设计单入口单出口的模块

➢ 警告软件工程师不要使模块间出现内容耦合。当从顶部进入模块并且
从底部退出来时,软件是比较容易理解的,因此也是比较容易维护的。
7. 模块功能应该可以预测
➢ 模块的功能应该能够预测,但也要防止模块功能过分局限。
➢ 功能可预测:如果一个模块可以当做一个黑盒子,只要输入的数据相
同就产生同样的输出,这个模块的功能就是可以预测的。

7. 模块功能应该可以预测

5.4 描绘软件结构的图形工具

5.4.1 层次图和HIPO图

层次图

在这里插入图片描述

HIPO图

加粗样式

5.4.2 结构图

在这里插入图片描述
在这里插入图片描述

层次图和结构图总结

在这里插入图片描述

5.5 面向数据流的设计方法

  • 面向数据流的设计方法定义了一些不同的“映射”,利用这些映射可以把数据流图变换成软件结构。
  • 因为任何软件系统都可以用数据流图表示,所以面向数据流的设计方法理论上可以设计任何软件的结构。通常所说的结构化设计方法(简称SD方法),也就是基于数据流的设计方法。

5.5.1 概念

1.变换流

在这里插入图片描述

2. 事务流

在这里插入图片描述

3. 设计过程

在这里插入图片描述

5.5.2 变换分析

1. 设计步骤

(1) 复查基本系统模型
• 确保系统的输入数据和输出数据符合实际。
(2) 复查并精化数据流图
• 对需求分析阶段得出的数据流图认真复查,并且在必要时进行精化。
• 不仅要确保数据流图给出了目标系统的正确的逻辑模型,而且应该使数据
流图中每个处理都代表一个规模适中相对独立的子功能。
(3) 确定数据流图具有变换特性还是事务特性
• 一个系统中的所有信息流都可以认为是变换流,但是,当遇到有明显事
务特性的信息流时,建议采用事务分析方法进行设计。确定数据流的全
局特性和局部特性。
(4) 确定输入流和输出流的边界,从而孤立出变换中心
• 输入流和输出流的边界和对它们的解释有关,不同设计人员可能会在流
内选取稍微不同的点作为边界的位置。
(5) 完成“第一级分解”。
• 位于软件结构最顶层的控制模块Cm协调下述从属的控制功能:
• 输入信息处理控制模块Ca,协调对所有输入数据的接收;
• 变换中心控制模块Ct,管理对内部形式的数据的所有操作;
• 输出信息处理控制模块Ce,协调输出信息的产生过程。
在这里插入图片描述
(6) 完成“第二级分解”
• 处理映射成软件结构中一个适当的模块。完成第二级分解的方
法是:
• 从变换中心的边界开始逆着输入通路向外移动,把输入通路中每个处理
映射成软件结构中Ca控制下的一个低层模块;
• 然后沿输出通路向外移动,把输出通路中每个处理映射成直接或间接受
模块Ce控制的一个低层模块;
• 最后把变换中心内的每个处理映射成受Ct控制的一个模块。
在这里插入图片描述
在这里插入图片描述
(7) 使用设计度量和启发式规则对第一次分割得到的软件结构进一步精化
• 为了产生合理的分解,得到尽可能高的内聚、尽可能松散的耦
合,为了得到一个易于实现、易于测试和易于维护的软件结构,
应该对初步分割得到的模块进行再分解或合并。

5.5.3 事务分析

5.5.4 设计优化

• 设计优化应该力求做到在有效的模块化的前提下使用最少量的模块,以及在能够满足信息要求的
前提下使用最简单的数据结构。
• 对于时间是决定性因素的应用场合,可能有必要在详细设计阶段,也可能在编写程序的过程中进
行优化。
• 软件开发人员应该认识到,程序中相对说比较小的部分(典型地,10%~20%),通常占用全部处理
时间的大部分(50%~80%)。对时间起决定性作用的软件进行优化:
• 在不考虑时间因素的前提下开发并精化软件结构;
• 在详细设计阶段选出最耗费时间的那些模块,仔
细地设计它们的处理过程,以求提高效率;
• 使用高级程序设计语言编写程序;
• 在软件中孤立出那些大量占用处理机资源的模块;
• 必要时重新设计或用依赖于机器的语言重写上述
大量占用资源的模块的代码,以求提高效率。

5.6 小结

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我会为你解答关于编译原理课程设计的问题。首先,让我们来了解下编译原理的基本概念。 编译原理是指翻译高级语言程序的一门学科,它主要研究如何将高级语言程序翻译成机器语言程序。编译原理的主要任务是设计和实现编译器。 针对你的问题,我们来分步骤地回答: 第一步:环境部署 首先,我们需要安装一些必要的工具,例如编译器、文本编辑器等。在这里,我们可以选择使用C++语言来实现计算器,因为C++语言是一种高效、灵活的编程语言,可以很好地满足我们的需求。 在安装好必要的工具之后,我们需要编写一些基本的代码,例如定义数据类型、变量、函数等。 第二步:需求分析 在这个阶段,我们需要明确计算器的功能和要求,例如支持加减乘除和括号,能够处理整数和浮点数等。 我们还需要确定计算器的界面设计和交互方式,例如通过命令行界面或者图形界面来输入和输出计算结果。 第三步:总体设计 在这个阶段,我们需要根据需求分析的结果,设计计算器的总体结构和算法,例如如何处理加减乘除和括号等运算符,如何处理整数和浮点数等数据类型。 我们还需要考虑如何进行错误处理,例如输入非法字符或者除数为0等错误情况。 第四步:详细设计与实现 在这个阶段,我们需要根据总体设计的结果,进行详细的代码设计和实现。具体来说,我们可以采用词法分析、语法分析和语义分析等技术来实现计算器的编译器。 词法分析可以将输入的字符串分解成符号序列,例如将“2+3*4”分解成“2”、“+”、“3”、“*”、“4”等符号。 语法分析可以根据语法规则构建语法树,例如将“2+3*4”构建成一个二叉树,其中根节点为“+”,左子树为“2”,右子树为“3*4”。 语义分析可以对语法树进行计算,例如对“2+3*4”的语法树进行计算得到14。 最后,我们需要对代码进行测试和调试,确保计算器能够正确地处理各种输入情况,并且能够输出正确的计算结果。 以上就是编译原理课程设计一个简单的计算器的基本流程,希望能够对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绕球飞行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值