设计模式 · DEEP DIVE · 起点

设计模式:学会读意图,而不是背类图

大多数人学设计模式靠背 UML 类图。这条路有一个致命缺陷——策略和状态的类图一模一样,装饰器、代理、适配器、外观都是「包一层」。靠结构,这些模式永远分不开。这份教程换一条路:抓住「读意图」这一个判断角度,把 14 个最常被混淆的模式连成一体。

0.0这份教程想解决的问题

翻开任何一本模式书,每个模式都配一张 UML 类图。多数人于是把学习等同于「背下每张类图,面试时默写」。这条路有一个隐藏的失败模式,而且躲不开:策略(Strategy)和状态(State)的类图完全相同;装饰器、代理、适配器、外观四个模式都是「在对象外面包一层」,结构几乎一致;桥接(Bridge)和策略的结构也一样。

当两个模式的类图相同,背结构就无法把它们分开。遇到真实问题——「这里该用策略还是状态?」——脑子里浮现两张相同的图,给不出答案。这不是学得不够熟,是用错了区分维度:类图区分不了它们,意图才能。

这份教程属于概念导向:目标是建立「何时用哪个」的判断力,而不是默写代码。它用语言无关的伪代码讲结构,把笔墨集中在最难、也最值钱的那件事上——在一堆长得一样的模式里,认出谁是谁。

0.1读者定位

适合谁

  • 有 2-3 年面向对象经验、用过框架(如 Spring),但没系统学过设计模式的工程师。
  • 能读伪代码,理解类与接口、继承与组合的区别。本教程语言无关,用伪代码讲结构。
  • 背过几个模式、但一到真实代码就分不清该用哪个的人——这正是本教程的主战场。

不适合谁

  • 没写过面向对象代码的初学者——先补 OOP 基础(类、接口、继承、组合),否则前置概念会让你掉队。推荐先读 Refactoring.Guru 的 OOP 与模式入门。
  • 只想查「某语言里某模式的 API 怎么写」的人——去看该语言文档更快。

读完之后你能做到什么

  • 看一段代码,先问「它把哪一处变化隔离了、为了什么意图」——于是策略/状态、装饰器/代理这些「双胞胎」第一次能被你一眼分开。这是文档不会教、而五年经验的工程师才有的读法。
  • 对 14 个模式中的每一个,说出它分离出去的是什么(算法 / 状态 / 创建方式 / 接口差异),并据此反推该不该用它。
  • 在三组「类图几乎相同」的模式里——策略vs状态、四个 wrapper、桥接vs策略——靠意图而非结构把它们区分开。
  • 判断什么时候不该用模式:认出过度设计(为一个永远只有一种实现的算法引入策略接口),知道哪些模式已被现代语言特性吸收。

0.2一句话本质

下面这段是整份教程的地基。每读完一章,回到这里再读一遍——它会越来越具体。

① 设计模式的名字记录的是「意图」,不是类图。

② 大量模式的结构几乎一样(都是「组合 + 接口」那一套),因为它们都在用同样的两种机制封装变化;正因如此,你无法靠类图区分模式,只能靠意图。

「封装变化」= 把代码里一处你预期将来会改的地方,隔离到一个稳定的接口 / 角色后面,让它能独立替换、不波及其余代码。这是「关注点分离」在面向对象里的具体落地。它是引擎——解释了模式为什么存在、为什么长得像;但它太抽象,无法告诉你该用哪个模式。真正能区分模式的,是上一句的「意图」。

所以:背 UML 必然失败(类图会重复),要记的是「这个模式把什么分了出去、为了什么」。

0.3现状速览(截至 2026-06)

这门知识今天处于什么状态

GoF 的 23 个模式自 1994 年定稿,模式本身没变;变的是专业判断。截至 2026,三件事值得先知道:

稳定:松耦合、面向接口、组合优于继承这些原则,以及模式作为团队共享词汇的价值,依然成立。

已演变:约 16/23 个模式被现代语言特性吸收——lambda 让策略/命令缩成「传一个函数」,DI 容器接管了工厂/单例,sealed 类 / enum + 模式匹配表达状态。Peter Norvig 1996 年就指出了这一点,至今成立。

已被取代:单例(Singleton)从「最好教的模式」翻转成几乎公认的反模式(隐藏全局状态、破坏测试),现代做法是依赖注入。

这一层判断不是脚注——它决定你写出的是好设计还是 cargo-cult(照搬仪式)。第 05 章专门把它讲透。

0.4概念地图(骨架)

把下面这张图记在心里。它只画骨架:从引擎「封装变化」出发,经过一条因果链,落到最关键的判断「读意图」,再分出三类模式。完整的 14 个模式清单在 0.5 模式索引表查。

引擎:封装变化 把会变的一处隔离到稳定接口后 靠两种机制:面向接口编程 · 组合优于继承 结构到处都是「组合+接口」 所以 无法靠类图区分模式 → 只能读意图(关键) 创建型 分离:对象怎么来 工厂方法 · 抽象工厂 建造者 · 单例 结构型 分离:在外面套一层 适配器 · 装饰器 · 代理 外观 · 桥接 · 组合 行为型 分离:会变的行为 策略 · 状态 · 观察者 模板方法 ⚠ 横跨三组的「双胞胎」:结构像,意图不同 策略╌状态 · 装饰器╌代理╌适配器╌外观 · 桥接╌策略 · 组合╌装饰器 第 03、04、05 章逐一拆开
图 0.1所有模式都从顶部那句「封装变化」长出来,经因果链落到最关键的「读意图」,再分三类。注意:底部那条「双胞胎」横带——它们分属不同的组,结构却几乎一样,这正是为什么本教程把「读意图」而不是「背结构」当主线。

骨架图把「双胞胎」压成了一行字。它们是全教程最难的部分,值得单独看一眼下面这张图:四组模式各自结构相同,真正的区别只在意图。

策略 状态 ≈类图全等 区别:谁触发转移 适配器 装饰器 代理 外观 ≈ 都是「包一层」 区别:改不改接口 / 谁控制 / 意图 桥接 策略 ≈ 同结构 区别:两维度独立 vs 一个算法 组合 装饰器 ≈ 都是递归树 区别:N个子节点聚合 vs 1个子节点加责任
图 0.2四组「双胞胎」,每组上方标「为什么像」,下方标「真正的区别」。注意:四组的区别全是意图层面的(谁触发、谁控制、几个维度),没有一组能靠类图分开——这就是「读意图」的含义。

0.5模式索引表

本教程聚焦 14 个最常被混淆、辨析价值最高的 GoF 模式。✓ = 正文深讲;○ = 作辨析对比 / 镜像;△ = 延伸提及。

表 0.1 · 本教程模式覆盖范围(14 个 GoF 模式 + 简单工厂踏脚石)
分类模式本教程怎么处理
创建型工厂方法、抽象工厂、建造者、单例✓ 正文深讲(第 02 章)
创建型简单工厂✓ 踏脚石(非 GoF)
结构型适配器、装饰器、代理、外观、桥接、组合✓ 正文深讲(第 03 章)
行为型策略、状态、观察者、模板方法✓ 正文深讲(第 04 章)
行为型中介者○ 观察者处作对比
行为型命令、职责链、迭代器、访问者△ 延伸提及
创建型原型△ 延伸提及

GoF 共 23 个模式。本教程不逐个讲完——挑出 14 个辨析价值最高的深讲,其余留作延伸。把「读意图」的判断力建立起来后,剩下的模式你能自己套进同一个框架。

0.6学习路径

主线是线性的,六章按依赖顺序推进。顶部的面包屑(每章高亮当前位置)就是这条路径:

learning-pathorder
[01 地基] → [02 创建型] → [03 结构型] → [04 行为型] → [05 辨析与判断]
  封装变化       对象怎么来      在外面套一层    把行为抽出来     强制你做选择
  +读意图主线    辨析创建家族     wrapper四兄弟    策略vs状态王牌    跨章辨析+该不该用

分场景路径

  • 只想真正理解模式:01 → 02 → 03 → 04 → 05,顺序读完。这是默认路径。
  • 已会用、只想学会辨析:快读 01 抓住「读意图」主线,直接跳 03(wrapper 四兄弟)和 04(策略vs状态),再做 05 的跨章辨析。
  • 带读 / review 他人代码:先看 01 + 05 建立「这段代码用了哪个模式、该不该用」的判断,再回查具体模式章。

可跳读:若你已能脱口说出某章每个模式「分离出什么、意图是什么」,直接跳到 05 章对应辨析题验真;全对就跳过该章正文。

0.7读之前:一个关于「读懂了」的警告

设计模式读起来「很顺」是常态——每个模式单看都不难。但「顺」恰恰是最危险的信号:它叫流畅性幻觉。你以为掌握了,其实只是眼熟。真正的掌握只在「分不清两个模式」时才暴露。

自检:下面三句话出现时,停一下

「我读得很顺」——多半是眼熟,不是学会。

「我做题很快」——多半碰到的是套路题型。

「我没卡壳」——多半还没真正撞上「该用策略还是状态」这种坎。

本教程会故意在你最容易「想当然」的地方设辨析、延迟揭晓答案。卡住是设计好的,不是你的问题。

延伸阅读