5.3 软件设计
一句话讲明白
需求阶段解决"做什么",设计阶段解决"怎么做"——画出软件蓝图,把系统切成一块块好做、好改、好复用的模块。
生活类比
盖房子,需求是"三室两厅、朝南、能住四口人";设计则是施工图:承重墙在哪、水电怎么走、每个房间的尺寸多少。
施工图有个铁律——每个房间功能要单纯(卧室就是睡觉),房间之间靠门和走廊连,不能把厨房的下水直接捅进卧室墙里。换成软件术语就是:高内聚、低耦合。
正经定义
软件设计的目标是根据软件分析的结果完成软件构建过程,绘制软件蓝图,权衡各种技术和实施方法的利弊,合理分配资源,构建详细设计方案和相关模型,指导软件实施。从方法上分为结构化设计(SD)与面向对象设计(OOD)。
拆解与流程
一、结构化设计 SD
面向数据流的方法,以 SRS、DFD、数据字典为基础,自顶向下、逐层分解、逐步求精、模块化。
| 阶段 | 又名 | 主要任务 |
|---|---|---|
| 概要设计 | 总体结构设计 | 确定软件系统结构、划分模块、确定每个模块的功能、接口和调用关系,形成模块结构图(系统结构图 SC) |
| 详细设计 | — | 为每个模块设计实现细节(输入/输出、处理流程、数据存储、用户界面、安全性和可靠性设计) |
模块三属性:功能(做什么)、逻辑(内部怎么做)、状态(使用环境和条件)。先确定外部特性(模块名、参数表、对系统造成的影响),再确定内部特性(代码和内部数据)。
信息隐藏与抽象:模块应设计成"黑盒",外部只能用接口说明中给出的信息。
耦合(模块之间联系程度,越低越好)7 种,低 → 高:
非直接耦合 → 数据耦合 → 标记耦合 → 控制耦合 → 通信耦合(部分教材称外部耦合)→ 公共耦合 → 内容耦合
- 数据耦合:借参数传递简单数据;标记耦合:传记录等复杂数据结构;控制耦合:传的信息用于控制模块内部逻辑;公共耦合:多个模块访问同一个公共数据环境;内容耦合:直接访问另一个模块内部数据/有多个入口等(最该避免)。
内聚(模块内部联系紧密程度,越高越好)7 种,高 → 低:
功能内聚 → 顺序内聚 → 通信内聚 → 过程内聚 → 时间内聚 → 逻辑内聚 → 偶然内聚
铁律:高内聚、低耦合——内聚高则好理解好维护,耦合低则可独立开发维护。
详细设计的表示工具:图形工具(业务流程图、程序流程图、NS 流程图/盒图、PAD 图)、表格工具(判定表)、语言工具(PDL 伪码,可作注释插入源程序、可自动生成代码,但不如图形直观、复杂条件组合不如判定树清晰)。
二、面向对象设计 OOD
基本思想:抽象、封装、可扩展性(可扩展性主要通过继承和多态实现)。核心问题是同时提高可维护性和可复用性。
七大设计原则(必背):
| 原则 | 一句话 |
|---|---|
| 单一职责 | 一个类应该有且仅有一个引起它变化的原因,否则应拆分 |
| 开闭原则 | 对扩展开放、对修改封闭 |
| 里氏替换 | 子类可以替换父类,可扩展父类功能但不能改变父类原有功能 |
| 依赖倒置 | 依赖于抽象而非具体实现,针对接口编程 |
| 接口隔离 | 用多个专门接口好过单一总接口 |
| 组合重用(合成复用) | 尽量用组合而不是继承达到复用 |
| 迪米特(最少知识) | 一个对象应对其他对象尽可能少地了解,降低耦合 |
类的三种类型:
| 类型 | 干什么 | 特征 |
|---|---|---|
| 实体类 | 映射需求中的每个实体,存永久存储体的信息(学员类、课程类) | 一定有属性,不一定有方法 |
| 控制类 | 控制用例工作,动宾短语转化来的名词(身份验证器) | 没有属性,一定有方法 |
| 边界类 | 位于系统与外界交接处(窗口、报表、通信协议、打印机接口、传感器、终端) | 可既有属性也有方法 |
三、统一建模语言 UML
结构包括构造块、规则、公共机制三部分。构造块 = 事物 + 关系 + 图。
- 事物(建模元素)4 类:结构事物(类、接口、协作、用例、活动类、构件、节点,共 7 种)、行为事物(交互、状态机)、分组事物(包,只在开发阶段存在)、注释事物。
- 关系 4 种:依赖、关联、泛化、实现。
- UML 2.0 的 14 种图:类图、对象图、构件图、组合结构图、用例图、顺序图(序列图)、通信图(UML1.x 称协作图)、定时图、状态图、活动图、部署图、制品图、包图、交互概览图。
- 静态结构:类图、对象图、构件图、组合结构图、部署图、制品图、包图
- 动态行为:用例图、活动图、状态图;交互图四类:顺序图、通信图、定时图、交互概览图
- UML 5 个系统视图(4+1 视图):
| 视图 | 回答什么 |
|---|---|
| 用例视图 | 最基本的需求分析模型,从外部角色视角展示系统功能 |
| 逻辑视图(设计视图) | 系统静态结构和动态行为,功能怎么实现 |
| 进程视图 | 可执行线程和进程建模,描述并发与同步 |
| 实现视图 | 组成物理代码的文件和构件 |
| 部署视图 | 把构件部署到物理节点,软件到硬件的映射 |
四、设计模式
设计模式是前人经验的总结,包含模式名称、问题、目的、解决方案、效果、实例代码和相关设计模式等要素。
- 按处理范围:类模式(编译时刻确定的静态关系)/ 对象模式(运行时刻变化,更具动态性)。
- 按目的(必背三大类):
| 类型 | 干什么 | 典型模式 |
|---|---|---|
| 创建型 | 创建对象 | 工厂方法、抽象工厂、原型、单例、建造者 |
| 结构型 | 处理类或对象的组合 | 适配器、桥接、组合、装饰器、外观、享元、代理 |
| 行为型 | 描述类或对象的交互与职责分配 | 职责链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者 |
考试怎么考
- 题型:选择题高频,几乎每年必考 2-4 分;案例题偶尔考"设计不合理导致的返工"。
- 常见问法:
- "耦合度最低的是?" → 非直接耦合;"耦合度最高的是?" → 内容耦合
- "内聚度最高的是?" → 功能内聚;"最低的是?" → 偶然内聚
- "描述对象之间消息的时间次序,应选用?" → 顺序图
- "表示软件到硬件的映射和分布,是哪个视图?" → 部署视图
- "'对扩展开放、对修改封闭'指?" → 开闭原则;"一个对象应对其他对象尽可能少地了解" → 迪米特原则
- "某类没有属性但一定有方法" → 控制类;"一定有属性" → 实体类
- 陷阱词:把"高内聚低耦合"说成"高耦合低内聚";把 UML 的"部署图"和"部署视图"当成两个完全不同的概念(其实部署图是部署视图的图形载体)。
易混辨析
| 对比 | 概要设计 | 详细设计 |
|---|---|---|
| 关注 | 系统有哪些模块、模块间关系 | 模块内部算法与局部数据结构 |
| 依据 | SRS、DFD | 概要设计(详细设计不得影响概要设计,改概要设计须项目经理同意) |
| 对比 | 白盒/结构视角 | 黑盒/功能视角 |
|---|---|---|
| 设计里体现为 | 关注模块内部逻辑 | 关注模块外部接口(详见 5.4 软件实现) |
一秒记忆
"设 计 三 句:耦 合 从 低 到 高 非 数 标 控 通 公 内(内容耦合最坏),内 聚 从 高 到 低 功 顺 通 过 时 逻 偶(偶然内聚最烂)。UML 五视图:用逻进实部(用例、逻辑、进程、实现、部署)。设计模式三大家:建造型、结构型、行为型——'建 结 行'。"