软考
23种GoF设计模式速查表
软考高级系统架构设计师备考:创建型/结构型/行为型 23 种 GoF 设计模式,含意图/结构/适用场景/类图/真题高频考点
一句话定位
本表覆盖软考 §3.8 设计模式,是综合知识(35 题)与案例分析(设计模式应用判断)的重点。要求做到 23 种模式意图清晰、10 个高频模式”给场景能选对”。
NOTE
- 综合知识:给场景/类图让判断用了哪种模式(选择题),或让选择合适的设计模式
- 案例分析:给出系统问题,要求选择并说明理由(“使用了什么模式?为什么?”)
- 论文:可能要求”论述在某系统中设计模式的应用”(需结合项目实例)
A. 设计模式概述
A.1 设计模式分类体系
GoF《设计模式》按目的分为三类:
| 类别 | 数量 | 核心关注点 | 记忆口诀 |
|---|---|---|---|
| 创建型 (Creational) | 5 种 | 对象的创建机制 | ”单原抽建工” |
| 结构型 (Structural) | 7 种 | 类/对象的组合关系 | ”适桥组装外享代” |
| 行为型 (Behavioral) | 11 种 | 对象间的职责分配与通信 | ”策命观中迭状责命解访” |
A.2 设计模式六要素
| 要素 | 说明 |
|---|---|
| 模式名 | 具有特定含义的词汇(如”观察者”、“工厂方法”) |
| 意图 (Intent) | 模式的目的和作用 |
| 别名 (Also Known As) | 其他常见叫法 |
| 动机 (Motivation) | 什么场景下需要这个模式 |
| 结构 (Structure) | 类图/对象图的组成关系 |
| 适用性 (Applicability) | 什么条件下使用 |
B. 创建型模式(Creational,5种)
关注对象创建,将对象的创建与使用分离
B.1 三种工厂模式对比(高频★★★)
| 模式 | 核心思想 | 英文 | 一句话意图 | 结构特征 | 适用场景 |
|---|---|---|---|---|---|
| 简单工厂 | 一个工厂类,根据不同参数返回不同产品 | Simple Factory | 用一个工厂类封装所有产品的创建 | 一个工厂类 + 一个创建方法 | 产品种类少且不频繁变化 |
| 工厂方法 | 将产品创建延迟到子类 | Factory Method | 定义创建对象的接口,让子类决定实例化哪个类 | 抽象工厂 + 具体工厂;一个工厂对应一个产品 | 需要扩展产品系列时 |
| 抽象工厂 | 创建相关/依赖产品族 | Abstract Factory | 创建一系列相关或相互依赖的对象,而无需指定具体类 | 多个工厂方法组合;每个工厂产出一族产品 | 需要多个相关产品族时 |
WARNING
区分工厂三兄弟:
- 简单工厂:一个工厂类做所有事(不属于 GoF,但常考)
- 工厂方法:一个工厂对应一个产品,延迟到子类决定
- 抽象工厂:一个工厂对应一族产品,创建的是产品族
B.2 创建型模式详解(5种)
| 模式 | 意图 | 核心结构 | 真题示例 |
|---|---|---|---|
| ① 单例 (Singleton) | 确保一个类只有一个实例,提供全局访问点 | 私有构造 + 静态实例 + 双重检查锁/饿汉/懒汉 | 数据库连接池、日志对象 |
| ② 原型 (Prototype) | 通过克隆现有对象创建新对象 | 实现 Clone 接口;浅拷贝 vs 深拷贝 | 复制已有对象,不重新初始化 |
| ③ 生成器/建造者 (Builder) | 将复杂对象的构建与表示分离,分步构造 | Director + Builder + ConcreteBuilder + Product | 构造 SQL 语句、复杂配置对象 |
| ④ 工厂方法 (Factory Method) | 定义创建接口,子类决定实例化哪个类 | Creator + ConcreteCreator + Product + ConcreteProduct | 日志工厂(FileLogger/DBLogger) |
| ⑤ 抽象工厂 (Abstract Factory) | 创建相关/依赖产品族 | AbstractFactory + ConcreteFactory + AbstractProduct + ConcreteProduct | UI 库(Windows/Mac 按钮/文本框族) |
B.3 创建型模式类图——以”工厂方法”为例
C. 结构型模式(Structural,7种)
关注类/对象的组合,形成更大的结构
C.1 四种”包装”模式辨析(高频★★★)
| 模式 | 英文 | 核心意图 | 对”谁”做包装 | 包装后变化 | 类比 |
|---|---|---|---|---|---|
| 适配器 | Adapter | 转换接口,让不兼容的类协同工作 | 被适配者 | 接口变了(旧接口 → 新接口) | 转接头 |
| 桥接 | Bridge | 抽象与实现分离,两者独立变化 | 实现部分 | 分离了两个维度 | 走桥 |
| 装饰 | Decorator | 动态给对象添加职责 | 被装饰对象 | 功能增强(外观不变) | 穿衣服 |
| 代理 | Proxy | 控制对对象的访问 | 被代理对象 | 访问控制(外观不变) | 经纪人 |
IMPORTANT
适配器 vs 桥接 vs 装饰 vs 代理——四胞胎分清:
- 适配器:解决”接口不兼容”(改变接口)
- 桥接:解决”继承爆炸”(分离两个独立变化的维度)
- 装饰:解决”动态扩展功能”(不改变接口,层层叠加职责)
- 代理:解决”间接访问/控制”(不改变接口,控制访问时机/方式)
C.2 结构型模式详解(7种)
| 模式 | 意图 | 关键特征 | 典型场景 |
|---|---|---|---|
| ⑥ 适配器 (Adapter) | 转换接口,使不兼容类协作 | 类适配器(继承)/ 对象适配器(组合) | 兼容旧接口、第三方库适配 |
| ⑦ 桥接 (Bridge) | 抽象部分与实现部分分离,独立变化 | 两个继承层次:抽象层 + 实现层 | 跨平台 UI、多种数据库驱动 |
| ⑧ 组合 (Composite) | 树形结构表示”部分-整体”,统一处理 | Component + Leaf + Composite | 文件系统、组织架构、UI 控件树 |
| ⑨ 装饰 (Decorator) | 动态给对象添加职责,比继承灵活 | Decorator 持有 Component 引用,层层叠加 | 给流加缓冲、给组件加边框 |
| ⑩ 外观 (Facade) | 为子系统提供统一的高层接口 | 简化复杂子系统的使用 | 复杂 API 封装、SDK 入口 |
| ⑪ 享元 (Flyweight) | 共享细粒度对象,减少内存 | 内部状态(共享)vs 外部状态(独立) | 字符串池、围棋棋子、粒子系统 |
| ⑫ 代理 (Proxy) | 控制对对象的访问 | 远程代理/虚拟代理/保护代理/智能引用 | 延迟加载、访问控制、远程调用 |
C.3 结构型模式类图——以”装饰模式”为例
D. 行为型模式(Behavioral,11种)
关注对象间的职责分配与通信机制
D.1 高频辨析:状态 vs 策略 vs 命令
| 模式 | 英文 | 核心意图 | ponsibility 分配 | 关键特征 | 类比 |
|---|---|---|---|---|---|
| 状态 | State | 状态改变时改变行为 | 对象内部状态变化 | 状态类封装行为,自动切换 | 心情好/坏表现不同 |
| 策略 | Strategy | 封装可互换的算法族 | 外部传入不同策略 | 算法族可互换,客户端决定 | 多种出行方式可选 |
| 命令 | Command | 将请求封装为对象 | 解耦发送者与接收者 | 支持撤销、排队、日志 | 遥控器 |
WARNING
状态 vs 策略——最易混淆的一对:
- 状态模式:行为由内部状态决定,状态类之间可自动切换(如:订单待支付→已支付→已发货)
- 策略模式:行为由客户端选择传入,策略之间不自动切换(如:支付时选择支付宝/微信/银行卡)
一句话区分:状态是”我现在是什么状态,就做什么行为”;策略是”客户选哪个策略,就执行哪个算法”
D.2 行为型模式详解(11种)
| 模式 | 意图 | 关键结构 | 真题高频场景 |
|---|---|---|---|
| ⑬ 责任链 (Chain of Responsibility) | 沿链传递请求,直到有对象处理 | Handler + ConcreteHandler,链式结构 | 多级审批、异常处理链、拦截器 |
| ⑭ 命令 (Command) | 将请求封装为对象,支持撤销/排队/日志 | Invoker + Command + Receiver + ConcreteCommand | 撤销(Undo)、队列、宏命令 |
| ⑮ 解释器 (Interpreter) | 给定语言,定义文法并解释句子 | Expression + TerminalExpression + NonterminalExpression | 正则表达式、简单脚本引擎 |
| ⑯ 迭代器 (Iterator) | 顺序访问聚合元素,不暴露内部表示 | Iterator + ConcreteIterator + Aggregate + ConcreteAggregate | Java Iterator、遍历集合 |
| ⑰ 中介者 (Mediator) | 用中介对象封装一组对象的交互 | Mediator + ConcreteMediator + Colleague | 聊天室、MVC 中的Mediator |
| ⑱ 备忘录 (Memento) | 不破坏封装下保存并恢复对象内部状态 | Originator + Memento + Caretaker | 撤销操作、快照、存档 |
| ⑲ 观察者 (Observer) | 一对多依赖,状态变化时通知所有观察者 | Subject + Observer + ConcreteSubject + ConcreteObserver | 发布订阅、事件监听 |
| ⑳ 状态 (State) | 对象状态改变时改变其行为 | Context + State + ConcreteState | 订单状态机、线程状态 |
| ㉑ 策略 (Strategy) | 封装可互换的算法族 | Context + Strategy + ConcreteStrategy | 排序策略、支付策略 |
| ㉒ 模板方法 (Template Method) | 定义算法骨架,子类重写特定步骤 | AbstractClass + ConcreteClass | 框架设计、生命周期回调 |
| ㉓ 访问者 (Visitor) | 不改变类前提下对元素定义新操作 | Visitor + ConcreteVisitor + Element + ConcreteElement | 编译器 AST 遍历、报表生成 |
D.3 行为型模式类图——以”观察者模式”为例
E. 高频模式”场景→模式”匹配表(Case & 选择题核心)
综合知识常考”以下场景最适合哪种设计模式”,掌握以下匹配是关键。
E.1 高频场景速查(10个必背)
| 场景描述 | 匹配模式 | 关键词 |
|---|---|---|
| 一个类只能有一个实例(如数据库连接池) | 单例 (Singleton) | 唯一实例、全局访问 |
| 创建一系列相关/配套的产品族(Windows/Mac UI) | 抽象工厂 (Abstract Factory) | 产品族、相关对象 |
| 复杂对象的构建步骤多且可调(SQL 构建器) | 生成器/建造者 (Builder) | 分步构造、Director |
| 需要兼容两个不兼容的接口 | 适配器 (Adapter) | 接口转换、兼容 |
| 多种算法/策略可互换(排序/支付/促销) | 策略 (Strategy) | 算法族、可互换 |
| 对象状态变化时自动改变行为(订单状态流转) | 状态 (State) | 状态机、自动切换 |
| 一个对象变化通知多个依赖对象 | 观察者 (Observer) | 发布订阅、事件 |
| 多层处理/审批,沿链传递直到处理 | 责任链 (Chain of Responsibility) | 链式、逐层传递 |
| 给对象动态添加功能,层层叠加 | 装饰 (Decorator) | 动态增强、叠加 |
| 控制对对象的访问(延迟加载/权限控制) | 代理 (Proxy) | 间接访问、控制 |
E.2 进阶场景辨析(易错)
| 场景 | 易误选 | 正确答案 | 理由 |
|---|---|---|---|
| 文件系统,目录和文件统一处理 | 组合 (Composite) | ✅ 组合 (Composite) | “部分-整体”树形结构 |
| 遍历集合但不暴露内部结构 | 迭代器 (Iterator) | ✅ 迭代器 | 分离遍历与集合 |
| 撤销操作,不破坏封装 | 命令 (Command) | ✅ 备忘录 (Memento) | 保存的是状态快照 |
| 撤销操作,需要记录操作历史 | 备忘录 (Memento) | ✅ 命令 (Command) | 记录的是操作本身 |
| 一组对象间复杂的通信,减少耦合 | 中介者 (Mediator) | ✅ 中介者 | 封装交互、减少依赖 |
| 行为的扩展,不改变原有类 | 装饰 (Decorator) | ✅ 访问者 (Visitor) | 访问者新增的是操作不是职责 |
F. 易混模式对比表(Case 答题核心)
F.1 包装/代理类对比
| 模式 | 包装目的 | 接口是否变化 | 使用频率 |
|---|---|---|---|
| 适配器 | 接口转换 | ✅ 变化(旧 → 新) | ★★★ |
| 桥接 | 分离两个维度 | ❌ 无变化 | ★★ |
| 装饰 | 动态增强功能 | ❌ 无变化 | ★★★ |
| 代理 | 控制访问 | ❌ 无变化 | ★★★ |
F.2 行为类易混对比
| 对比组 | A 模式 | B 模式 | 核心区别 |
|---|---|---|---|
| 状态 vs 策略 | 状态:内部状态决定行为,自动切换 | 策略:外部传入决定算法,手动切换 | 触发来源:内部 vs 外部 |
| 命令 vs 责任链 | 命令:封装请求为对象,支持撤销/队列 | 责任链:沿链传递请求,直到处理 | 命令是”记录”,责任链是”传递” |
| 观察者 vs 中介者 | 观察者:一对多通知 | 中介者:多对多通信,中心协调 | 数量关系:1:N vs M:N |
| 模板方法 vs 策略 | 模板方法:算法骨架固定,子类填步骤 | 策略:整个算法可替换 | 替换粒度:部分 vs 整体 |
G. 记忆口诀与速记(考前背诵)
G.1 分类口诀
创建五:单原抽建工
单例、原型、抽象工厂、建造者、工厂方法
结构七:适桥组装外享代
适配器、桥接、组合、外观、享元、代理、(装饰?)
→ 修正:适(适配器)桥(桥接)组(组合)装(装饰)外(外观)享(享元)代(লক্ষণ代理)
行为十一:策命观中迭状责命解访
策略、命令、观察者、中介者、迭代器、状态、责任链、备忘录、解释器、模板方法、访问者
G.2 高频模式速记
| 模式 | 一句话 | 考法 |
|---|---|---|
| 单例 | ”一”个实例 | 唯一性判断 |
| 工厂方法 | ”子”类决定 | 延迟实例化 |
| 抽象工厂 | ”族”的产品 | 产品族匹配 |
| 适配器 | ”转”接口 | 不一致 → 一致 |
| 装饰 | ”加”功能 | 层层叠加 |
| 代理 | ”控”访问 | 间接控制 |
| 观察者 | ”通”知多 | 一对多 |
| 策略 | ”换”算法 | 可互换 |
| 状态 | ”变”行为 | 状态切换 |
| 责任链 | ”链”处理 | 逐级传递 |
G.3 案例题”识别模式”答题套路
当案例分析问”使用了什么设计模式?“时,按以下结构作答:
答题模板:
使用了 [模式名] 模式。
理由:题目中描述的 [具体场景/问题] 符合 [模式名] 的意图——[模式的定义]。
具体来说:
- [特征 1]
- [特征 2](类图/代码中的体现)
使用 [模式名] 的好处是 [好处 1] 和 [好处 2]。
示例:
系统中有多种支付方式(支付宝/微信/银行卡),客户端可以灵活选择。请问使用了什么设计模式?
答:使用了策略模式。因为系统存在多种可互换的支付算法(策略),客户端可以根据需要选择不同的支付策略。具体来说,各支付方式实现统一的支付接口,上下文(Context)持有策略引用并在运行时切换。使用策略模式的好处是算法可独立变化、客户端与算法解耦。
H. 交叉引用与关联阅读
| 相关主题 | 位置 | 关联内容 |
|---|---|---|
| 计算机基础 | 01-cs-fundamentals.mdx | PV 操作、内存管理、范式 |
| 软件工程与 UML | 02-software-engineering-uml.mdx | 开发模型、UML 九图、类间关系 |
| 架构 → 设计模式应用 | 03-architecture-core.mdx | 架构风格、质量属性 |
| 新技术 | 05-new-tech-web-arch.mdx(待产) | 微服务设计模式(BFF、CQRS、Saga) |
| 案例分析模板 | 06-case-analysis-template.mdx(待产) | 设计模式在案例中的答题套路 |
I. 自测题(检验掌握程度)
-
以下场景最适合哪种设计模式?:一个图形编辑器需要支持给图形添加边框、阴影等装饰效果。
点击查看答案
装饰模式 (Decorator)。核心特征:动态给对象添加职责,不改变原有对象结构,可层层叠加。类似”穿衣服”一层层加。 -
以下场景最适合哪种设计模式?:图书馆有多种搜索策略(按书名、作者、ISBN),用户可以灵活选择。
点击查看答案
策略模式 (Strategy)。核心特征:封装可互换的算法族,由客户端选择具体策略。注意:虽然是”选择”行为,但这里的”搜索”是可互换的算法,由外部传入而非内部状态自动切换,所以是策略而非状态。 -
状态模式和策略模式的核心区别是什么?
点击查看答案
触发来源不同:- 状态模式:行为由内部状态决定,状态类之间可以自动切换(如:订单状态流转)
- 策略模式:行为由客户端传入决定,策略之间不自动切换(如:支付时选择不同支付方式)
一句话:状态是”我现在是什么状态,就做什么”;策略是”客户让我用哪个,我就用哪个”。
- 状态模式:行为由内部状态决定,状态类之间可以自动切换(如:订单状态流转)
-
适配器、装饰、代理三者的核心区别是什么?
点击查看答案
三者都是”包装”模式,但目的不同:- 适配器:解决接口不兼容问题(旧接口 → 新接口)
- 装饰:动态给对象添加新职责(不改变接口)
- 代理:控制对对象的访问(不改变接口,增加间接层)
区别在于意图:适配器是”转换”,装饰是”增强”,代理是”控制”。
- 适配器:解决接口不兼容问题(旧接口 → 新接口)
-
观察者模式和中介者模式都是处理对象间通信,有什么区别?
点击查看答案
- 观察者:一对多依赖关系(1:N),Subject 直接通知 Observer,Observer 之间互不知晓
- 中介者:多对多通信(M:N),所有对象通过 Mediator 协调,减少对象间直接依赖
区别在于:观察者解决的是”谁通知谁”的问题,中介者解决的是”太多对象互相引用”的问题。
- 观察者:一对多依赖关系(1:N),Subject 直接通知 Observer,Observer 之间互不知晓
IMPORTANT
如果自测题只能”看着面熟”但说不清楚,建议重读对应章节并结合真题练习。设计模式题的本质是**“给场景 → 选模式”,不在于记住类图的所有细节,而在于快速匹配意图**。
下一篇导引:新技术与 Web 架构速查表(待产) 将涵盖微服务、云原生、容器、DevOps 以及 Serverless、秒杀、性能测试等近年高频新技术方向。