7.5.3 模块设计
本课核心知识点整理
模块设计是本章高频考点
课堂明确说模块设计在软件设计师考试中“必考并且考得非常多”。核心就是:模块设计原则、高内聚低耦合、各种内聚和耦合的定义辨析。
基本原则
| 原则 | 解释 |
|---|---|
| 模块大小适中 | 太大职责混杂,太小接口和管理成本高 |
| 扇入扇出适中 | 扇入是被多少模块调用,扇出是调用多少模块 |
| 调用深度适中 | 层次过深会增加理解和调试成本 |
| 单入口单出口 | 控制结构清晰,避免非正常入口和跳转 |
| 功能可预测 | 看到模块名和接口能理解它负责什么 |
| 作用域尽量小 | 判定影响范围尽量在本模块内部 |
扇入和扇出不要极端化理解。常说“多扇入、少扇出”,但考试中更稳妥的原则是适中。
作用域和控制域
| 概念 | 含义 |
|---|---|
| 控制域 | 某模块本身以及它能直接或间接调用的模块集合 |
| 作用域 | 某个判定条件会影响到的模块范围 |
原则:判定的作用域应尽量控制在本模块内,通常希望作用域小于或落在控制域之内。
内聚性:模块内部有多“团结”
内聚看模块内部元素之间的联系。目标是高内聚。
| 内聚类型 | 强度 | 关键词 |
|---|---|---|
| 功能内聚 | 最高 | 完成一个单一明确功能 |
| 顺序内聚 | 高 | 前一处理元素输出作为后一处理元素输入,按顺序执行 |
| 通信内聚 | 较高 | 围绕同一数据结构或同一数据集合操作 |
| 过程内聚 | 中 | 按特定次序执行,但不一定前一输出是后一输入 |
| 时间内聚 | 较低 | 一组任务在同一时间段执行 |
| 逻辑内聚 | 低 | 逻辑上相关的一组任务 |
| 偶然/巧合内聚 | 最低 | 任务之间无明显关系或松散关系 |
容易混淆点:
| 类型 | 区分 |
|---|---|
| 顺序内聚 | 有明确数据流,前者输出是后者输入 |
| 过程内聚 | 只是必须按特定次序,不强调输出输入关系 |
| 时间内聚 | 同一时间段完成,例如初始化、清理等 |
| 通信内聚 | 集中在同一数据结构或数据区域上 |
耦合性:模块之间有多“纠缠”
耦合看模块之间的依赖关系。目标是低耦合。
| 耦合类型 | 强度 | 关键词 |
|---|---|---|
| 非直接耦合 | 最低 | 模块之间没有直接关系 |
| 数据耦合 | 低 | 通过参数传递简单数据 |
| 标记耦合 | 较低 | 通过参数传递记录、结构体等复杂数据 |
| 控制耦合 | 中 | 传递控制信息,影响被调模块逻辑 |
| 外部耦合 | 较高 | 多模块依赖同一全局简单变量或外部环境 |
| 公共耦合 | 高 | 多模块共享同一公共数据环境 |
| 内容耦合 | 最高 | 直接访问他人内部、非正常入口、代码重叠、多入口 |
数据耦合和标记耦合最容易混:简单变量是数据耦合,一组相关数据、记录、结构体是标记耦合。
为什么要低耦合
模块之间依赖越强,一个模块变化就越容易牵连其他模块。修一个 bug 可能引入更多 bug,测试范围也会扩大。因此低耦合能降低维护、回归测试和变更成本。
例题
一个模块只完成一个单一明确的功能,属于:
两个模块通过参数传递一条记录或结构体,属于:
某模块直接访问另一个模块内部数据或从非正常入口进入,属于:
自查要点
- 内聚和耦合分别看模块内部还是模块之间?
- 内聚最高和最低分别是什么?
- 耦合最低和最高分别是什么?
- 数据耦合和标记耦合如何区分?
- 为什么低耦合能减少回归测试范围?