返回知识库 软考
23 种 GoF 设计模式逐个详解
创建型 5 + 结构型 7 + 行为型 11,每种含意图/结构/角色/适用场景/真题考法/易混对比;含 SOLID 设计原则与高频易混对比表
更新于 2026年7月29日
软考设计模式GoF真题SOLID案例分析
一句话定位
案例题要求识别”某 UML 类图是哪种模式”、“该场景应选哪种模式”、“某模式有几个角色”——本篇把 23 种 GoF 模式每种独立详讲到看 UML 即可识别。
NOTE
本篇是 04-design-patterns.mdx 的”模式独立深化版”。事实据教材第 2 版 §3.8 + GoF 经典 + 2020-2025 真题核对(2026-07-29)。
IMPORTANT
每种模式 6 要素:① 一句话意图 ② UML 结构图 ③ 角色 ④ 适用场景 ⑤ 真题考法 ⑥ 易混模式对比
三大类区分
| 类型 | 数量 | 关注 |
|---|
| 创建型 Creational | 5 | 对象创建(封装实例化) |
| 结构型 Structural | 7 | 类/对象组合(接口适配) |
| 行为型 Behavioral | 11 | 对象间职责分配(通信) |
一、创建型(5)
A1 单例 Singleton
| 维度 | 内容 |
|---|
| 意图 | 确保一个类只有一个实例,提供全局访问点 |
| 结构 | 单例类持私有静态实例 + 私有构造 + 公有静态获取方法 |
| 角色 | Singleton(唯一角色) |
| 5 种实现 | 饿汉式 / 懒汉式 / 双重检查锁 DCL / 静态内部类 / 枚举(推荐) |
| 适用 | 配置管理 / 日志 / 数据库连接池 / Spring Bean 单例 / Runtime |
| 真题 | 2021-11 综合、2024-05 综合 |
| 易混 | vs 全局变量:单例有封装 + 懒加载 + 唯一性保证 |
双重检查锁实现:
class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
A2 工厂方法 Factory Method
| 维度 | 内容 |
|---|
| 意图 | 定义创建接口,延迟到子类决定实例化哪个类 |
| 结构 | Product(抽象产品)+ ConcreteProduct + Creator(抽象工厂)+ ConcreteCreator |
| 角色 | 4 角色 |
| 适用 | 不确定具体类型 / 解耦创建与使用 / 框架扩展点 |
| 典型 | 日志工厂(File/DB/Console 日志);Spring BeanFactory |
| 真题 | 2018-05、2022-11 综合(UML 类图识别) |
| 易混 | vs 简单工厂(无开放封闭原则)/ vs 抽象工厂(产品族 vs 单产品) |
Creator ──uses──> Product
△ △
│ │
ConcreteA ──creates──> ConcreteProductA
ConcreteB ──creates──> ConcreteProductB
A3 抽象工厂 Abstract Factory
| 维度 | 内容 |
|---|
| 意图 | 创建一系列相关或依赖的对象族 |
| 结构 | AbstractFactory + ConcreteFactory + AbstractProduct(多个)+ ConcreteProduct |
| 角色 | 4 角色,但每工厂含多个创建方法 |
| 适用 | 跨 UI 主题(Windows/Mac 按钮 + 文本框 + 下拉)/ 数据库多类型(MySQL/PG/Oracle DAO) |
| 典型 | Java AWT Toolkit / Spring 多 DataSource |
| 真题 | 2020-11、2025-05 综合 |
| 易混 | vs 工厂方法:工厂方法创 1 种,抽象工厂创一族 |
A4 生成器 Builder
| 维度 | 内容 |
|---|
| 意图 | 将复杂对象的构建与表示分离,分步构造 |
| 结构 | Director(指挥者)+ Builder(抽象)+ ConcreteBuilder + Product |
| 角色 | 4 角色 |
| 适用 | 复杂对象(多参数构造)/ SQL 构造器 / StringBuilder / Lombok @Builder |
| 典型 | StringBuilder / Protocol Buffers |
| 真题 | 2023-11 综合(生成器角色) |
| 易混 | vs 工厂:生成器关注”分步过程”,工厂关注”创建哪种” |
A5 原型 Prototype
| 维度 | 内容 |
|---|
| 意图 | 通过克隆原型实例创建新对象 |
| 结构 | Prototype(抽象,含 clone())+ ConcretePrototype + Client |
| 角色 | 3 角色 |
| 关键 | 浅拷贝 vs 深拷贝 |
| 适用 | 创建开销大(DB 查询)/ 配置初始化 / 防止类层次爆炸 |
| 典型 | Java Object.clone() / 原型模式 Spring |
| 真题 | 2022-05 综合(深浅拷贝) |
WARNING
浅拷贝 vs 深拷贝:
- 浅拷贝:基本类型复制值;引用类型复制引用(共享对象)
- 深拷贝:递归克隆所有引用对象
二、结构型(7)
B1 适配器 Adapter
| 维度 | 内容 |
|---|
| 意图 | 转换接口,使不兼容类协作 |
| 结构 | Target(目标接口)+ Adaptee(被适配者)+ Adapter |
| 两类 | 类适配器(继承 Adaptee 实现 Target)/ 对象适配器(组合 Adaptee,推荐) |
| 角色 | 3 角色 |
| 适用 | 旧接口适配新系统 / 第三方库集成 |
| 典型 | Java InputStreamReader(字节→字符)/ Spring HandlerAdapter |
| 真题 | 2019-11、2024-11 综合 |
| 易混 | vs 桥接 vs 装饰(适配器改接口,装饰增职责不改接口) |
B2 桥接 Bridge
| 维度 | 内容 |
|---|
| 意图 | 将抽象部分与实现部分分离,独立变化 |
| 结构 | Abstraction(抽象)+ RefinedAbstraction + Implementor(实现接口)+ ConcreteImplementor |
| 角色 | 4 角色 |
| 关键 | 通过组合而非继承连接两个独立维度 |
| 适用 | 跨平台 UI(形状 × 颜色)/ 跨数据库驱动 / JDBC Driver |
| 典型 | JDBC(DriverManager 桥接 Driver)/ Java Logging |
| 真题 | 2021-05 综合 |
B3 组合 Composite
| 维度 | 内容 |
|---|
| 意图 | 树形结构表示”部分-整体”,统一处理叶子和组合 |
| 结构 | Component(抽象)+ Leaf(叶子)+ Composite(组合,含子节点集合) |
| 角色 | 3 角色 |
| 适用 | 文件系统(文件 + 文件夹)/ 组织架构 / UI 控件树 / 菜单 |
| 典型 | Java Swing Container / AWT Component |
| 真题 | 2024-05 综合 |
B4 装饰 Decorator
| 维度 | 内容 |
|---|
| 意图 | 动态给对象添加职责,比继承更灵活 |
| 结构 | Component + ConcreteComponent + Decorator(实现 Component + 持有 Component)+ ConcreteDecorator |
| 角色 | 4 角色 |
| 关键 | 装饰器与原对象同接口 + 持有原对象引用 |
| 适用 | Java IO 流(InputStream → BufferedInputStream → DataInputStream)/ 咖啡加料(基础+牛奶+糖) |
| 典型 | Java IO / Spring BeanWrapper |
| 真题 | 2020-05 综合、2025-11 综合 |
BufferedInputStream(InputStream in)
└─ DataInputStream(InputStream in)
└─ FileInputStream("file.txt")
B5 外观 Facade
| 维度 | 内容 |
|---|
| 意图 | 为子系统提供统一高层接口 |
| 结构 | Facade(外观,组合多个子系统)+ Subsystem(多个) |
| 角色 | 2 角色(Facade + Subsystems) |
| 适用 | 复杂子系统封装(计算机启动:CPU+内存+硬盘一起启动)/ SLF4J |
| 典型 | Spring JdbcTemplate / SLF4J |
| 真题 | 2023-05 综合 |
B6 享元 Flyweight
| 维度 | 内容 |
|---|
| 意图 | 共享细粒度对象,减少内存 |
| 结构 | Flyweight(抽象)+ ConcreteFlyweight(共享)+ UnsharedFlyweight + FlyweightFactory |
| 角色 | 4 角色 |
| 关键 | 内部状态(共享,不随环境变)+ 外部状态(不共享,调用方传入) |
| 适用 | 围棋棋子(颜色内部状态,位置外部)/ 字符串常量池 / 数据库连接池 / Integer Cache |
| 典型 | Java String pool / Integer.valueOf(-128~127) |
| 真题 | 2022-11 综合 |
B7 代理 Proxy
| 维度 | 内容 |
|---|
| 意图 | 为其他对象提供代理以控制访问 |
| 结构 | Subject(抽象)+ RealSubject(被代理)+ Proxy(持有 RealSubject) |
| 角色 | 3 角色 |
| 4 类 | 远程 Remote(RPC)/ 虚拟 Virtual(懒加载)/ 保护 Protective(权限)/ 智能引用 Smart(计数/缓存) |
| 适用 | Spring AOP / RPC Stub / 图片懒加载 / 权限校验 |
| 典型 | Spring AOP(JDK 动态代理 / CGLIB) |
| 真题 | 2017-11、2024-05 综合 |
三、行为型(11)
C1 责任链 Chain of Responsibility
| 维度 | 内容 |
|---|
| 意图 | 沿链传递请求,直到处理 |
| 结构 | Handler(抽象,含 successor)+ ConcreteHandler(多个) |
| 角色 | 2 角色 |
| 关键 | 解耦发送者与接收者;接收者决定处理或传给下一个 |
| 适用 | 审批流 / Servlet 过滤器(Filter Chain)/ Spring Interceptor / OA 系统 |
| 典型 | Java Servlet Filter / Spring HandlerInterceptor |
| 真题 | 2021-11 综合 |
C2 命令 Command
| 维度 | 内容 |
|---|
| 意图 | 将请求封装为对象,支持撤销/排队/日志 |
| 结构 | Command(声明 execute)+ ConcreteCommand + Receiver(实际执行)+ Invoker(调用者)+ Client |
| 角色 | 5 角色 |
| 适用 | 编辑器撤销/重做 / 任务队列 / 事务管理 / 宏命令 |
| 典型 | Java Runnable / Spring Transaction |
| 真题 | 2024-11 综合 |
C3 解释器 Interpreter
| 维度 | 内容 |
|---|
| 意图 | 给定语言,定义文法并解释句子 |
| 结构 | AbstractExpression + TerminalExpression(终结符)+ NonterminalExpression(非终结符)+ Context + Client |
| 角色 | 5 角色 |
| 适用 | 正则引擎 / SQL 解析 / 规则引擎 / 表达式求值 |
| 典型 | Spring SpEL / Java regex |
| 真题 | 2025-05 综合(与规则系统对照) |
C4 迭代器 Iterator
| 维度 | 内容 |
|---|
| 意图 | 顺序访问聚合元素,不暴露内部表示 |
| 结构 | Iterator(hasNext/next)+ ConcreteIterator + Aggregate(容器抽象)+ ConcreteAggregate |
| 角色 | 4 角色 |
| 适用 | 集合遍历(List/Set/Map)/ 文件遍历 / 流式处理 |
| 典型 | Java Iterator / Iterable |
| 真题 | 2018-05 综合 |
| 维度 | 内容 |
|---|
| 意图 | 用中介对象封装一组对象交互,解耦对象间网状关系 |
| 结构 | Mediator + ConcreteMediator + Colleague(同事类)+ ConcreteColleague |
| 角色 | 4 角色 |
| 关键 | 网状交互 → 星型(都通过中介者) |
| 适用 | 聊天室 / 飞机调度系统 / 事件总线 / MVC 中 Controller 充当 Mediator |
| 典型 | Java Timer / Spring EventBus |
| 真题 | 2023-11 综合 |
C6 备忘录 Memento
| 维度 | 内容 |
|---|
| 意图 | 在不破坏封装下保存并恢复对象内部状态 |
| 结构 | Originator(原发器,创建/恢复备忘录)+ Memento(保存状态)+ Caretaker(管理者,仅持有不修改) |
| 角色 | 3 角色 |
| 适用 | 游戏存档 / 事务回滚 / 编辑器撤销 / 检查点 |
| 典型 | Java Serializable / Spring Transaction |
| 真题 | 2022-05 综合 |
C7 观察者 Observer(最高频)
| 维度 | 内容 |
|---|
| 意图 | 一对多依赖,状态变化时通知所有观察者 |
| 结构 | Subject(主题,attach/detach/notify)+ ConcreteSubject + Observer(update)+ ConcreteObserver |
| 角色 | 4 角色 |
| 关键 | 推模型(主题发送数据)vs 拉模型(观察者主动取) |
| 适用 | 事件订阅 / MVC(View 监听 Model)/ Vue 双向绑定 / 消息总线 |
| 典型 | Java Observable / Observer / Spring ApplicationEvent |
| 真题 | 2017-11、2020-11、2024-05 综合(高频!) |
C8 状态 State
| 维度 | 内容 |
|---|
| 意图 | 对象状态改变时改变其行为(看上去像换了类) |
| 结构 | Context(持 State 引用)+ State(抽象)+ ConcreteState(多个) |
| 角色 | 3 角色 |
| 适用 | 订单状态机(待支付/已支付/已发货/已完成)/ 自动售货机 / 工作流 |
| 典型 | Spring StateMachine |
| 真题 | 综合 |
| 易混 | vs 策略:状态自动切换(环境管理状态),策略客户端主动选 |
C9 策略 Strategy(高频)
| 维度 | 内容 |
|---|
| 意图 | 封装可互换的算法族,可互换 |
| 结构 | Strategy(抽象算法)+ ConcreteStrategy(多个)+ Context(持 Strategy) |
| 角色 | 3 角色 |
| 关键 | 客户端选择具体策略;与状态模式结构相同但意图不同 |
| 适用 | 支付方式(微信/支付宝/银行卡)/ 排序算法 / 折扣计算 / 路径规划 |
| 典型 | Java Comparator / Spring 多种 Bean 注入 |
| 真题 | 2021-05、2025-05 综合 |
C10 模板方法 Template Method
| 维度 | 内容 |
|---|
| 意图 | 定义算法骨架,子类重写特定步骤 |
| 结构 | AbstractClass(templateMethod + primitiveOp)+ ConcreteClass(实现 primitiveOp) |
| 角色 | 2 角色 |
| 关键 | 父类定义流程(final),子类实现细节 |
| 适用 | JUnit 测试生命周期 / Spring 框架钩子 / Servlet doGet/doPost |
| 典型 | Java InputStream.read() / Spring JdbcTemplate |
| 真题 | 2023-05 综合 |
C11 访问者 Visitor
| 维度 | 内容 |
|---|
| 意图 | 在不改变类前提下对元素定义新操作 |
| 结构 | Visitor(visit ConcreteElement)+ ConcreteVisitor + Element(accept Visitor)+ ConcreteElement + ObjectStructure |
| 角色 | 5 角色 |
| 关键 | 双重分派 Double Dispatch(accept 调 visit,visit 又调具体 element 方法) |
| 适用 | 编译器 AST / 文件树导出(不同访问者做不同操作)/ 报表生成 |
| 典型 | Java ASM 字节码操作 |
| 真题 | 2024-11 综合(双分派) |
四、设计原则(综合题常考)
SOLID 五原则
| 原则 | 全称 | 含义 |
|---|
| S - SRP | Single Responsibility | 单一职责:一个类只有一个变化原因 |
| O - OCP | Open-Closed | 开闭:对扩展开放,对修改关闭 |
| L - LSP | Liskov Substitution | 里氏替换:子类必须能替换父类 |
| I - ISP | Interface Segregation | 接口隔离:客户端不被迫依赖不用的方法 |
| D - DIP | Dependency Inversion | 依赖倒置:依赖抽象,不依赖具体 |
其他原则
- 迪米特法则 LoD(Least Knowledge):一个对象应对其他对象保持最少了解
- 合成复用原则 CRP:多用组合,少用继承
- KISS(Keep It Simple, Stupid):保持简单
- DRY(Don’t Repeat Yourself):避免重复
五、易混模式对比表
| 对比项 | 模式 A | 模式 B | 关键区别 |
|---|
| 创建 | 工厂方法 | 抽象工厂 | 1 种 vs 1 族 |
| 创建 | 工厂方法 | 生成器 | 关注哪种 vs 关注分步 |
| 结构 | 适配器 | 装饰 | 改接口 vs 增职责 |
| 结构 | 适配器 | 桥接 | 事后改 vs 设计初分 |
| 结构 | 代理 | 装饰 | 控制访问 vs 增职责 |
| 结构 | 组合 | 装饰 | 都用递归;组合关注树结构 |
| 行为 | 状态 | 策略 | 自动切换 vs 客户端选 |
| 行为 | 命令 | 策略 | 封装请求 vs 算法族 |
| 行为 | 观察者 | 中介者 | 一对多广播 vs 星型中介 |
六、反查表
| 模式 | 类型 | 意图一句话 | 角色 | 真题 |
|---|
| 单例 | 创建 | 唯一实例 | 1 | 2021-11, 2024-05 |
| 工厂方法 | 创建 | 子类决定实例化 | 4 | 2018-05, 2022-11 |
| 抽象工厂 | 创建 | 创建产品族 | 4 | 2020-11, 2025-05 |
| 生成器 | 创建 | 分步构建 | 4 | 2023-11 |
| 原型 | 创建 | 克隆 | 3 | 2022-05 |
| 适配器 | 结构 | 接口转换 | 3 | 2019-11, 2024-11 |
| 桥接 | 结构 | 抽象-实现分离 | 4 | 2021-05 |
| 组合 | 结构 | 部分-整体树 | 3 | 2024-05 |
| 装饰 | 结构 | 动态增职责 | 4 | 2020-05, 2025-11 |
| 外观 | 结构 | 子系统统一接口 | 2 | 2023-05 |
| 享元 | 结构 | 共享对象 | 4 | 2022-11 |
| 代理 | 结构 | 控制访问 | 3 | 2017-11, 2024-05 |
| 责任链 | 行为 | 链式传递 | 2 | 2021-11 |
| 命令 | 行为 | 封装请求 | 5 | 2024-11 |
| 解释器 | 行为 | 文法解释 | 5 | 2025-05 |
| 迭代器 | 行为 | 顺序遍历 | 4 | 2018-05 |
| 中介者 | 行为 | 中介封装交互 | 4 | 2023-11 |
| 备忘录 | 行为 | 状态保存恢复 | 3 | 2022-05 |
| 观察者 | 行为 | 一对多通知 | 4 | 2017-11, 2020-11, 2024-05 |
| 状态 | 行为 | 状态切行为 | 3 | 综合 |
| 策略 | 行为 | 算法互换 | 3 | 2021-05, 2025-05 |
| 模板方法 | 行为 | 算法骨架 | 2 | 2023-05 |
| 访问者 | 行为 | 双分派扩展 | 5 | 2024-11 |
记忆口诀 / 易错点汇总
- 创建型 5:单工抽生原(单例/工厂/抽象工厂/生成器/原型)
- 结构型 7:适桥组装外享代(适配器/桥接/组合/装饰/外观/享元/代理)
- 行为型 11:责命解迭中备观状策模访
- SOLID 五原则:单一职责 + 开闭 + 里氏替换 + 接口隔离 + 依赖倒置
- 观察者 = 一对多通知;中介者 = 多对多解耦
- 策略 vs 状态:策略客户端选;状态自动切
TIP
避坑建议:
- 看 UML 类图:是否有”持 X 引用”+“同接口” → 装饰 / 代理 / 适配器
- 装饰与原对象同接口;代理控制访问;适配器改接口
- 工厂方法创1 种,抽象工厂创1 族
- 状态机用状态模式(不是策略)
交叉引用
本系列笔记
主计划文档
详见 主计划 §3.8 设计模式 的对应内容。
外部延伸
- 官方教材:《系统架构设计师教程(第 2 版)》§3.8
- 经典著作:GoF《Design Patterns: Elements of Reusable Object-Oriented Software》
- 真题练习:2020-2025 综合+案例
自测题
- 创建:写”配置管理类”应选哪种模式?(答:单例)
- 结构:Java IO 流的 BufferedInputStream 是什么模式?(答:装饰)
- 结构:JDBC DriverManager 是什么模式?(答:桥接)
- 行为:观察者与中介者的核心区别?(答:一对多广播 vs 多对多中介)
- 行为:订单状态机用什么模式?(答:状态,不是策略)
- 行为:Java Runnable 是什么模式?(答:命令)
IMPORTANT
如果只能”看着面熟”但说不出来,说明还没真正掌握,建议回看对应章节并多做真题。
下一篇导引:微服务分布式深化 将讲述微服务全栈(注册/网关/熔断/限流/分布式事务),覆盖案例与论文新高频方向。