00|Java 25 设计模式学习指南:24 种模式、OOP 思路与配套代码
配套代码:GitHub 仓库与运行说明 · 24种模式源码目录。使用 JDK 25、Gradle Wrapper 9.6.1,包名前缀为
com.hanserwei.patterns。
系列导航:本篇 · 下一篇:OOP 与工程基础
验证环境:JDK 25.0.3 / Gradle 9.6.1。24 个独立示例与 49 项行为测试已运行通过,代码包名前缀统一为
com.hanserwei.patterns。
设计模式适合从“代码为什么越来越难改”开始学习。增加一种导出格式,为什么要改很多控制器?给文本加两种能力,为什么子类成倍增加?文章进入已归档状态后,哪些操作应该被拒绝?这些问题分别涉及创建决策、对象组合和行为协作。模式给出的,是反复出现的问题及一组有代价的解决办法。
本系列使用 Java 和标准 OOP 风格:通过接口表达契约,通过类封装状态与行为,通过构造器暴露依赖;需要继承时解释父子类关系,需要组合时解释谁持有谁。示例围绕博客内容、主题、通知、草稿和校对展开,但每种模式保留独立包,避免读到后面才发现必须先启动一整套应用。
先说清楚:为什么这里是 24 种
GoF 的《Design Patterns: Elements of Reusable Object-Oriented Software》收录 23 种设计模式。本文采用 GoF 23 种 + 简单工厂 的学习口径,合计 24 种。简单工厂是帮助理解创建职责的补充,不把它写成 GoF 的第 24 种。原书与分类可参阅出版社介绍及目录。
| 类别 | GoF 数量 | 本系列内容 | 主要问题 |
|---|---|---|---|
| 创建型 | 5 | 加上简单工厂,共 6 篇 | 谁决定创建什么对象,如何得到有效对象 |
| 结构型 | 7 | 7 篇 | 对象怎样组合,接口和共享边界在哪里 |
| 行为型 | 11 | 11 篇 | 对象怎样分配职责、传递请求与协作 |
文章一共 27 篇:1 篇导航、1 篇基础、24 篇模式详解和1篇选型复盘。模式编号与文章编号不同,例如第02篇是第1个模式“简单工厂”,第25篇是第24个模式“访问者”。
配套代码
配套代码仓库:Hanserwei/design-patterns-java25。 仓库公开提供24种模式的完整实现、Gradle Wrapper 和行为测试。文章与代码独立维护,下文的源码路径均相对于仓库根目录。
仓库使用 Gradle Wrapper 9.6.1,Java Toolchain 和编译目标都固定为 25;运行不需要 Spring、数据库、网络服务或预览特性。首次使用 Wrapper 和下载测试、检查工具依赖需要联网,依赖缓存齐全后可以离线运行。
在配套代码仓库根目录执行:
java -version
./gradlew --version
./gradlew clean check
./gradlew runAll
./gradlew runStrategy
./gradlew test --tests 'com.hanserwei.patterns.strategy.PatternTest'
Windows 终端使用 gradlew.bat 替换 ./gradlew。建议让 JAVA_HOME 指向完整的 JDK 25;如果本机还安装了多个版本,同时核对终端、IDE 的 Gradle JVM 和 Gradle 检测到的 Toolchain。不要把 JRE 当作可以编译代码的 JDK。
check 同时运行行为测试、Google 风格检查、格式一致性检查和全成员 Javadoc 检查。formatJava 用于主动格式化,javadoc 生成 API 文档;测试报告位于 build/reports/tests/test/index.html。完整命令、目录表和验证记录见仓库 README 与 验证记录。
Gradle 从 9.1.0 开始支持使用 Java 25 运行,本系列固定较新的 9.6.1,避免不同读者用任意系统 Gradle 产生差异。版本兼容依据见 Gradle 官方兼容矩阵。
读每篇文章时做四件事
- 先看变化。 说清当前问题,以及哪个维度预计会变化。不要先背模式名称,再强行寻找使用机会。
- 跟一次调用。 从 Demo 进入接口、具体对象及其依赖,指出创建、委托、状态变化或短路发生在哪里。
- 运行并破坏一个契约。 运行测试,再尝试交换装饰顺序、传入非法状态或共享可变集合,看测试是否能发现错误。
- 完成扩展练习。 新增一个产品、算法、元素或状态,记录需要修改的文件,用改动范围评价这个设计是否适合实际变化。
每篇都包含问题背景、职责表、Mermaid 图、代码思路、关键源码、独立运行命令、测试要点、常见用法、边界、相近模式比较和练习。正文中的代码片段保留类、字段、构造器与方法注释,完整实现以配套仓库为准。
学习路线
第一次系统学习时,从01顺序往后读;每完成一组,就挑一个相近模式做比较。已有 Java 经验时,可以先读01中的契约与组合部分,再沿“创建三模式 → 装饰与代理 → 策略与状态 → 命令与备忘录 → 访问者”的路线建立对照,随后补齐其他章节。
flowchart LR
OOP[OOP 与工程基础] --> Creation[创建职责]
Creation --> Structure[组合与结构]
Structure --> Behavior[请求与协作]
Behavior --> Review[选型与综合复盘]
起步
创建型与简单工厂(02—07)
- 02|简单工厂:把产品选择集中到一个入口
- 03|工厂方法:让子类决定流程使用的产品
- 04|抽象工厂:一次切换相互匹配的产品族
- 05|建造者:把构建过程与有效对象分开
- 06|原型:复制状态之前先划清共享边界
- 07|单例:区分唯一实例、安全发布和共享状态
结构型(08—14)
- 08|适配器:把旧接口翻译成业务契约
- 09|桥接:拆开业务类型与实现方式两条变化轴
- 10|组合:让叶子与容器接受同一种操作
- 11|装饰器:通过包装逐层增加行为
- 12|外观:为多组件协作提供业务入口
- 13|享元:共享稳定状态,把变化留在外部
- 14|代理:在同一接口前控制真实访问
行为型(15—25)
- 15|责任链:让请求按明确规则经过处理节点
- 16|命令:把一次操作变成可保存的对象
- 17|解释器:用对象树表达一门小语言
- 18|迭代器:把遍历状态从集合中取出来
- 19|中介者:把同事之间的交互规则集中管理
- 20|备忘录:保存状态,同时守住对象封装
- 21|观察者:发布事实,让订阅者自行响应
- 22|状态:让合法动作随生命周期变化
- 23|策略:通过组合替换一组算法
- 24|模板方法:固定执行顺序,开放必要步骤
- 25|访问者:在稳定元素结构上持续增加操作
复盘
如何理解示例的取舍
本系列主要使用普通类与接口,不用 Lombok 自动隐藏字段和方法,也不靠框架注解替代对象协作。JDK 25 是运行与编译基线,模式本身不依赖某个新语法。少量 lambda 只用于测试回调和标准集合 API,主体仍保留具名类、显式构造器与多态方法。
示例默认单线程、进程内、内存数据;单例专题单独验证跨虚拟线程任务共享实例。凡是缓存、观察者、历史记录和生命周期示例,正文都会说明并发、资源或持久化边界。没有数据库事务、真实邮件发送或消息队列时,不把输出成功描述为生产流程已完成。
使用 Google Java Style 作为代码规范,并加上本系列更严格的注释约定:所有显式声明的类、接口、枚举、字段、构造器、方法和测试方法都写 Javadoc。检查工具负责格式与覆盖面,注释仍需由人判断是否讲清意图、单位、异常和所有权。规范原文见 Google Java Style Guide。
学习完成的标志,是面对一个新需求,能解释为什么选择某种职责划分,也能指出什么时候一个普通方法或简单分支已经足够。