1 为什么要进行分解模块化?

降低系统的开发难度,增加系统的可维护性。

2 总体(概要)设计的内容是什么。

  • 数据设计:数据结构
  • 体系结构设计:软件的主要结构性元素
  • 接口设计:软件内部,软件和协作系统之间以及软件同人之间如何通信。

总体设计的过程
总体设计通常由系统设计结构设计两个阶段组成。
系统设计阶段确定系统的具体实现方案,结构设计阶段确定软件的结构。

设计原则

模块化:将一个复杂的大系统分解成若干个相对简单的较小部分,称为子系统。

系统总体架构图 系统总体架构设计_系统总体架构图


设计原理:(老师给的答案:总体设计的内容)

  • 将系统划分成模块
  • 决定每个模块的功能
  • 决定模块的调用关系
  • 决定模块的界面,即模块间传递的数据

3 模块的定义,模块化设计的重要指导思想是什么。

定义:用一个名字可以调用的一段可执行程序语句

重要指导思想:实现模块化设计的重要指导思想是分解、信息隐藏和模块独立性。

模块具有输入和输出,功能,内部数据,程序代码等四个特性

模块是完成一个独立功能的程序单元。

模块独立性(module independence)概括了把软件划分为模块时要遵守的准则,也是判断模块构造是否合理的标准。

4 什么是耦合,举例1~2种了解的耦合方式。

耦合是模块之间的联系,用于衡量不同模块彼此间互相依赖(连接)的紧密程度。

  • 数据耦合:被调用模块的输入与输出是简单的参数或者是数据结构(该数据结构中的所有元素为被调用的模块使用),
  • 标记耦合:两个模块都要使用同一数据结构的一部分,不是采用全局公共数据区共享,而是通过模块结构传递数据结构的一部分
  • 控制耦合:两个模块中的一个模块给另一个模块传递控制信息
  • 外部耦合:模块与软件的外部环境联结在一起,受到约束时出现较高程度的耦合
  • 公共耦合:两个模块都可以存取相同的全局数据
  • 内容耦合:果两个模块中的一个直接引用了另一个模块的内容

模块独立性自下而上递增;耦合度自上而下递增。

5 为什么不能使用goto语句?可以例外使用goto语句的情况是什么?

原因:goto语句是无条件转移语句,它使得程序的控制流难以追踪,使得程序难以理解和修改;它可能跳过某些对象的构造、变量的初始化、重要的计算等语句,带来错误或隐患。

使用:终止程序在某些深度嵌套的结构中处理过程或跳转到异常处理。

6 为什么不能使用全局变量?

  • 作用域是整个程序,和函数的模块化编程相违背,不利于程序的修改、调试和移植,会破坏程序的结构性
  • 一定程度上造成内存浪费
  • 全局变量在任何地方都可以被修改,软件的安全性无法得到保证
  • 在面向对象的程序设计中,全局变量的初始化顺序不能确定,因编译器不同而不同,在面向对象的领域就变成了构造对象的顺序不确定,会造成无法预估的灾难性后果
    参考链接:为什么尽量少使用全局变量

7 控制耦合有什么副作用,如何解决?

副作用:尽管接口单一,但被控模块的内部逻辑仍然受到影响;控制模块必须知
道被控模块的内部逻辑,增强了相互依赖.

解决方法
1.面向过程技术的修改方法:在调用点进行条件判断;将被控模块按照子功能拆分使其变为控制模块与多个模块的数据耦合;
2.面向对象技术的解决方法,可以抽象出类和子类的情况,使用面向对象的“多态方法”解决。

8 标记耦合有什么副作用,如何解决?

个人理解:
副作用:标记耦合指两个模块之间传递的是数据结构,其实传递的是地址,数据可能在其他模块被修改,使输出结果受到影响。
解决方法:改标记耦合为数据耦合,将传递地址改为传递值。

9 模块之间联系的原则是什么?

  • 尽量使用数据耦合,少用控制耦合,限制公共耦合的范围,完全不用内容耦合。
  • 模块间相互调用时,传递参数最好只有一个。
  • 实现低耦合,耦合方式最好采用非直接耦合。
  • 使每个模块执行一个功能
  • 模块间传送数据型参数
  • 模块间共用信息尽量少

Ps:个人认为两种答案都可以

10 什么是内聚?

内聚是模块内部各成分之间的关系,用于衡量一个模块内部各个元素间彼此结合的紧密程度。

11 内聚有哪些类型?设计时应追求什么内聚?

  • 偶然内聚:无关的函数、过程或者数据出现在同一个模块里。模块内各部之间没有联系,或者即使有联系,这种联系也很松散。
  • 逻辑内聚:逻辑相关的函数或数据出现在同一个模块里。(逻辑上相似),把几种功能组合在一起,每次调用时,则由传递给模块的判定参数来确定该模块应执行哪一种功能。
  • 时间内聚:出现在同一个模块里是由于时间是相同的。(需要同时执行)
  • 过程内聚:出现在同一个模块里是由于处理的顺序。
  • 通信内聚:出现在同一个模块里是由于操作或者生成同一个数据集。(引用共同的数据)
  • 顺序内聚:一个处理元素的输出数据作为下一个处理元素的输入数据。
  • 功能内聚:模块内所有处理元素属于一个整体,完成一个单一的功能。
    应追求功能内聚

12 模块化的基本原则是什么。

高内聚,低耦合。
(内聚和耦合是密切相关的,模块内的高内聚往往意味着模块间的低耦合。内聚和耦合都是进行模块化设计的有力工具。实践表明,内聚更重要,应该把更多注意力集中到提高模块的内聚程度上。)
在实际工作中,确定内聚的精确级别是不必要的,重要的是力争高内聚和识别低内聚,可以使得设计的软件具有较高的功能独立性。

13 模块的评价标准。

  • 可分解性:模块是可分解的
  • 可组装性:模块是可组装的
  • 可理解性:模块可以被独立理解
  • 连续性:某个模块的修改不会导致整个系统的修改
  • 保护:异常限制在模块内

14 模块的功能可以预测是什么含义?

相同输入必产生相同输出。

15 什么是模块的深度、广度?划分的模块的时候,在深度广度上如何把控?

深度 = 分层的层数。过大表示分工过细。
宽度 = 同一层上模块数的最大值。过大表示系统复杂度大。

深度和宽度应适中

16 如何定义一个模块的扇入和扇出?

扇入 = 直接调用该模块的模块数
扇出 = 一个模块直接调用\控制的模块数

17 一个模块的控制域是什么?作用域又是什么?关系是什么?

定义
控制域指该模块本身以及所有直接或间接从属于它的模块;
作用域是指该模块中一个判断所影响的所有其它模块;
关系
模块的作用域应该在控制域之内

18 模块设计时的启发式规则有哪些

  • 改进软件结构提高模块独立性
  • 争取低耦合、高内聚
  • 模块规模适中(过大分解不充分不易理解;太小则开销过大、接口复杂)
  • 适当控制——深度 = 分层的层数(过大表示分工过细);宽度 = 同一层上模块数的最大值(过大表示系统复杂度大)
  • 深度、宽度、扇出和扇入应适中
  • 扇入 = 直接调用该模块的模块数
  • 扇出 = 一个模块直接调用\控制的模块数
  • 尽可能减少高扇出结构,随着深度增大扇入
    (扇出的控制:3或4,上限为5~9,扇入越大,说明复用性越好)
  • 如果一个模块的扇出数过大,就意味着该模块过分复杂,需要协调和控制过多的下属模块。应当适当增加中间层次的控制模块。
  • 一般来说,顶层扇出高,中间扇出少,低层高扇入。
  • 模块的作用域应该在控制域之内
  • 控制域指该模块本身以及所有直接或间接从属于它的模块
  • 作用域是指该模块中一个判断所影响的所有其它模块
  • 力争降低模块接口的复杂程度
  • 模块接口的复杂性是引起软件错误的一个主要原因。接口设计应该使得信息传递简单并且与模块的功能一致。
  • 设计单入口、单出口的模块
  • 避免内容耦合,易于理解和维护
  • 模块功能应该可以预测
  • 相同输入必产生相同输出
  • 反例:模块中使用全局变量或静态变量,则可能导致不可预测

19 什么是变化流,什么是事务流

信息沿输入通路进入系统,同时由外部形式变换成内部形式,进入系统的信息通过变换中心,经加工处理以后再沿输出通路变换成外部形式离开软件系统。当数据流图具有这些特征时,这种信息流就叫做变换流

数据沿输入通路到达一个处理T,这个处理根据输入数据的类型在若干个动作序列中选出一个来执行;由至少一条接受路径、一个事务中心和若干条动作路径组成的特殊数据流成为事务流

20 层次图,结构图是什么

层次图和HIPO图

层次图用来描绘软件的层次结构,很适于在自顶向下设计软件的过程中使用。

系统总体架构图 系统总体架构设计_模块化_02


HIPO 图(Hierarchy plus Input-Process-Output,HIPO)是IBM 公司于20 世纪70 年代中期在层次结构图的基础上推出的一种描述系统结构和模块内部处理功能的工具。

  • H图(层次图):描述软件总的模块层次结构
  • IPO图:描述每个模块输入、输出、处理功能及模块调用的详细情况,相当于为一个模块写的一份说明。

结构图

结构图是指以模块的调用关系为线索,用自上而下的连线表示调用关系并注明参数传递的方向和内容,从宏观上反映软件层次结构的图形。

系统总体架构图 系统总体架构设计_系统总体架构图_03


1.一个模块在结构图中只能出现一次。

2.一般习惯:输入模块在左,计算模块在中间,输出模块在右。

21 补充

模块化论据
 C(x)定义为问题x的感知复杂性
 E(x)定义为解决问题x所需要的工作量
 对p1和p2两个问题,
 若 C(p1) > C(p2),则 E(p1) > E(p2)
 C(p1 + p2) > C(p1) + C(p2)
 E(p1 + p2) > E(p1) + E(p2)
 Ps:不要过度模块化!每个模块的简单性将被集成的复杂性所掩盖。
信息隐藏

  • 模块内部的数据与过程,应该对不需要了解这些数据与过程的模块隐藏起来。只有那些为了完成软件的总体功能而必需在模块间交换的信息,才允许在模块间进行传递。
  • “隐蔽”意味着有效的模块化可以通过定义一组独立的模块而实现,这些独立的模块彼此间仅仅交换那些为了完成系统功能而必须交换的信息。
  • 这一指导思想的目的是为了提高模块的独立性,即当修改或维护模块时减少把一个模块的错误扩散到其他模块中去的机会。

自顶向下&自底向上
自顶向下设计的特点
a.易于修改和扩展
b.整体测试较易通过
c.需要进行详细的可行性论证
由底向上设计的特点
a.可能导致较大的重新设计
b.整体测试中可能在模块接口间发现不一致等问题
c.如果在可行性上出现问题,可以较早发现