主题
设计模式 · 导读
一句话:设计模式是对「一类反复出现的对象协作问题」的命名解法。学它的价值不在记住 23 个名字,而在遇到变化时能判断:这里该加一层间接,还是保持直白更便宜。
这套文档按「问题 → 机制 → 最小实现 → 误用代价」组织。示例用 Java 17,框架定位以 Spring Framework 6、MyBatis 3.5、Netty 4.1、JDK 17 为准,版本差异会在正文标注。
读之前需要什么
| 前置能力 | 具体检查 | 不满足时先补 |
|---|---|---|
| Java 面向对象 | 能读写接口、继承、组合、多态 | Java 基础语法 |
| 函数式接口 | 能读 Function<T,R>、Supplier<T>、lambda | java.util.function 包 |
| 并发基础 | 理解线程、可见性、synchronized、volatile 的基本语义 | JMM 内存模型 |
| 测试 | 能跑 JUnit 5,会写断言和参数化测试 | JUnit 5 用户指南 |
| 框架使用 | 用过 Spring 的依赖注入,知道 @Component 和 @Autowired | Spring IoC 容器原理 |
不要求先记完 23 种模式。本套只深入创建型、结构型、行为型里日常真正会用的部分,其余在对比表里给出定位。
阅读顺序
| 顺序 | 文档 | 回答的问题 | 读完应能 | 前置 |
|---|---|---|---|---|
| 1 | 01-六大设计原则 | 为什么这样组织代码,代价怎么量化 | 对每个原则举出一个反例,并说出拆分前后的可测差异 | 无 |
| 2 | 02-创建型模式 | 对象该由谁创建、创建几次、怎么构建 | 手写线程安全单例,解释 DCL 的每一步,排查容器与序列化下的重复实例 | 01 |
| 3 | 03-结构型模式 | 接口不匹配、功能要叠加、系统太复杂时怎么加一层 | 用 JDK 动态代理写一个可运行的增强器,判断代理/适配器/装饰器的意图差异 | 01 |
| 4 | 04-行为型模式 | 对象之间怎么协作而不硬编码 | 组装一条可排序、可短路的责任链,并为六种模式各指出一个真实使用点 | 01、02 |
| 5 | 05-设计模式在主流框架中的应用 | 怎么在源码里验证这些模式 | 把模式定位到具体的类和方法,而不是停留在类名猜测 | 02–04 |
建议节奏:每天一篇,读完立刻写一个不超过 50 行的可运行示例;第 5 天只做源码定位,不写新代码。
验收标准
| 验收项 | 判据 |
|---|---|
| 单例 | 能写出 DCL + volatile 版本和静态内部类版本;能解释 new 的三步与重排序;序列化/反射/多 ClassLoader 下各有一个防护或失效结论 |
| 工厂 | 能根据「产品是否成族、扩展频率」在简单工厂、工厂方法、抽象工厂之间选择,并说出各自改动点数量 |
| 结构型 | 能指出代理、适配器、装饰器在「接口是否相同、对象由谁创建、意图是什么」上的差异;能跑通一个 JDK 动态代理示例 |
| 行为型 | 能独立组装责任链(含顺序和中断),能说出策略与状态、模板方法与策略的区别 |
| 源码定位 | 能在 Spring、MyBatis、JDK、Netty 中各指出至少两个「类 + 方法」级别的模式落点 |
| 克制 | 能说出至少三种「不该用模式」的场景,并给出更简单的替代写法 |
目录结构
25_设计模式/
├── 00-设计模式学习路线.md ← 本页,只做导航
├── 01-六大设计原则.md ← SRP/OCP/LSP/ISP/DIP/LoD,反例与量化取舍
├── 02-创建型模式.md ← 单例、工厂家族、建造者、原型
├── 03-结构型模式.md ← 代理、适配器、装饰器、外观、桥接、组合、享元
├── 04-行为型模式.md ← 策略、责任链、观察者、模板方法、命令、状态
└── 05-设计模式在主流框架中的应用.md ← 类/方法级源码定位索引与其他主题的衔接
- 单例与
volatile:JMM 内存模型、动态代理与 CGLIB - 代理与 Spring AOP:Spring IoC 容器原理、05-设计模式在主流框架中的应用
- 责任链与网络处理:Netty ChannelPipeline 与 Handler
- 责任链与 MyBatis 插件:MyBatis 插件机制
初稿 2025-06 | 最后修订 2026-10