3.1 软件设计:从"做什么"到"怎么做"
两个层次 + 三个原则,概念题集中区。
| 层次 | 任务 | 产出 |
|---|---|---|
| 概要(总体)设计 | 划分模块、确定体系结构、模块间接口与数据设计 | 软件结构图、模块清单、接口说明 |
| 详细设计 | 给出每个模块的内部算法与数据结构(不写代码) | 模块流程图 / 伪代码 / PDL |
三个设计原则
- 模块化——把大系统拆成可管理的小模块(分而治之)。
- 抽象——忽略细节、只关注本质(分层抽象,从高层概念逐层细化)。
- 信息隐藏——模块内部的数据和实现细节对外不可见,只暴露必要接口; 这样改一个模块的内部,不影响其它模块。
课堂练习(2 题)
- 概要设计与详细设计的核心区别是什么? 答:概要设计确定"系统由哪些模块组成、怎么连",详细设计确定"每个模块内部怎么做"。
- 信息隐藏的好处是什么? 答:模块间影响最小化——内部实现可独立修改,降低了耦合、便于维护。
3.2 耦合:模块之间"绑得有多紧" ★
七级名单从低到高背下来,考试问"哪种最好/最差"。
耦合(Coupling)= 模块间联系的紧密程度。设计目标:越低越好。
| 级别(低 → 高) | 含义 | 好/坏 |
|---|---|---|
| 非直接耦合 | 模块之间没有任何直接联系(通过主控协调) | 最好 |
| 数据耦合 | 只通过参数传"简单数据"(传个数字/字符串) | 很好,实际系统的主要形态 |
| 标记(特征)耦合 | 传"整个数据结构",对方只用其中一部分 | 一般 |
| 控制耦合 | 传"控制信息"指挥对方内部逻辑(如传个 flag 让它走不同分支) | 较差 |
| 外部耦合 | 都依赖同一个外部环境/协议/设备 | 差 |
| 公共耦合 | 多个模块共享同一个全局数据区 | 差(牵一发动全身) |
| 内容耦合 | 一个模块直接访问另一个模块的内部(改人家私有变量、跳进别人代码) | 最差,严禁 |
记忆口诀
- 非数标控、外公内——从最好到最差:非直接、数据、标记、控制、外部、公共、内容。
- "看内容"(内容耦合)最恶劣,要尽量用数据耦合。
课堂练习(3 题)
- 哪种耦合最好?哪种最差? 答:非直接耦合最好;内容耦合最差。
- 模块 A 调用 B 时传了"整张学生表",B 只用到了姓名——这属于哪种耦合? 答:标记(特征)耦合。
- 传一个布尔开关参数控制对方走哪条分支,属于哪种耦合? 答:控制耦合(传的是控制信息而非单纯数据)。
3.3 内聚:模块内部"拧成一股绳"的程度 ★
七级名单从高到低背下来。设计目标:越高越好。
内聚(Cohesion)= 模块内部各成分结合的紧密程度。设计目标:越高越好。
| 级别(高 → 低) | 含义 | 例 |
|---|---|---|
| 功能内聚 | 模块只做一件事,所有成分为一个功能服务 | "计算平方根"模块 |
| 顺序内聚 | 各步骤顺序相关,前一步输出是后一步输入 | "先读数据再校验数据"在同一模块 |
| 通信内聚 | 各成分操作同一份数据 | 都围着"学生表"做增删改查 |
| 过程内聚 | 按固定流程组织,但处理的数据无关 | "先检查权限再打印"凑在一模块 |
| 时间内聚 | 因为"同一时间执行"被放一起 | "系统初始化"模块(各种无关初始化) |
| 逻辑内聚 | 一组逻辑相似但功能不同的动作打包 | 一个"输入"模块处理各种输入来源 |
| 偶然(巧合)内聚 | 成分之间毫无关系,纯属凑一起 | 把"打印"和"修改密码"放一个模块 |
记忆口诀
- 功顺通、过时逻偶——从最好到最差:功能、顺序、通信、过程、时间、逻辑、偶然。
- 好内聚的判断标准:这个模块能被一句话概括,并只做一件事 → 功能内聚。
易错
- 顺序内聚 vs 通信内聚:顺序是"上一步的输出喂给下一步",通信是"操作同一份数据"。
- "系统初始化"是时间内聚的经典例子——因为都要在系统启动时做才被绑在一起。
课堂练习(3 题)
- 哪种内聚最好?哪种最差? 答:功能内聚最好;偶然(巧合)内聚最差。
- "文件读取 + 数据校验 + 格式转换"放在一个模块,属于哪种内聚? 答:顺序内聚(前一步输出是后一步输入)。
- 设计时对耦合与内聚的追求分别是什么? 答:高内聚、低耦合。
3.4 UML 常用图速览
"什么图用来画什么"的配对题。
| 图 | 画什么 | 阶段 |
|---|---|---|
| 用例图 | 系统"给谁提供什么功能"(参与者 + 用例 + 关系) | 需求 |
| 类图 | 类的属性/方法 + 类间关系(继承、关联、聚合、组合、依赖) | 设计 |
| 时序(顺序)图 | 对象之间按时间顺序的消息交互 | 设计 |
| 活动图 | 业务流程/操作流程(类似流程图) | 分析/设计 |
| 状态图 | 一个对象的状态及转换(订单:待支付→已支付→已发货) | 设计 |
快速分辨
- 问"谁能用这个系统" → 用例图;问"类之间什么关系" → 类图;问"谁先调用谁" → 时序图。
课堂练习(2 题)
- 想展示"用户下单后系统内部对象之间的调用顺序",用哪种图? 答:时序图(顺序图)。
- 哪个 UML 图最常用于描述"系统的功能需求(谁做什么)"? 答:用例图。