这里不写模式的定义。两个问题值得回答:模式当初补的表达力缺口,如今由谁承担;留下来的模式要付出什么代价。
二十六篇文章,每篇一个模式,实验都在同一台机器(Apple M1 Pro)上跑两遍:JDK 21.0.8 与 JDK 25,源码引用逐字取自 JDK 25 的 src.zip。测量方法与局限写在每篇里,结论只建立在量级上。
总纲
| 文章 | 回答的问题 |
|---|---|
| 设计模式——被语言吃掉的那些模式 | 哪些 GoF 模式已被语言特性取代、哪些还留着,判据是哪三条 |
创建型
| 文章 | 回答的问题 |
|---|---|
| 设计模式——单例的五种写法与代价 | 五种写法各自把成本花在哪,哪种写法挡得住哪几种破坏 |
| 设计模式——建造者模式(Builder pattern) | 参与者有哪些,JDK 源码与 Lombok 各自怎么落地 |
| 设计模式——工厂方法:创建动作的成本 | 直接 new、Supplier、反射构造、方法句柄四条创建路的耗时与分配,以及反射 inflation 的一手验证 |
| 设计模式——抽象工厂:产品族的一致性 | 换一套实现的代价,以及族约束由编译器还是运行期兜底 |
| 设计模式——原型:拷贝的四条路 | clone、拷贝构造、深拷贝、序列化四者的耗时与分配差到几百倍,哪条路是浅拷贝 |
结构型
| 文章 | 回答的问题 |
|---|---|
| 设计模式——装饰器:缓冲链的代价 | 多包一层换来什么,缓冲层放错位置会怎样,flush 语义为什么不统一 |
| 设计模式——代理:动态代理的成本与边界 | 生成的代理类长什么样、缓存在哪、每次调用的分配从哪来、this 调用为什么绕开拦截 |
| 设计模式——适配器:边界在哪 | 适配层被内联之后成本测不出来,多实现调用点为什么让它重新出现 |
| 设计模式——桥接:两个维度独立变化 | m×n 的类爆炸值多少字节、多少类加载时间,多一层间接分派贵多少 |
| 设计模式——组合:树与叶子的同一接口 | 递归遍历与先展平的交叉点,栈深临界值,类型抹平的代价 |
| 设计模式——外观:批量接口的价值 | 细粒度调用收成批量之后 syscall 次数与耗时各降多少,Files.write 自带几层缓冲 |
| 设计模式——享元:共享不可变状态 | JDK 把缓存边界写在哪,-XX:AutoBoxCacheMax 改的是什么 |
行为型
| 文章 | 回答的问题 |
|---|---|
| 设计模式——责任链:三种形态 | 日志 Handler 链、Stream stage 链、HttpClient 过滤器链的成本曲线与短路位置的影响 |
| 设计模式——观察者:从 Observable 到背压 | 推模式缺的为什么是流量控制,SubmissionPublisher 缓冲写满时 submit 阻塞多久 |
| 设计模式——状态:状态位还是状态类 | JDK 用位标志加 CAS 管状态,状态类写法慢在哪,非法迁移的三种兜底值多少 |
| 设计模式——策略:有状态与无状态 | 策略有没有状态,成本落在调用上还是分配上 |
| 设计模式——命令:撤销栈与队列化 | 把调用变成对象之后买到什么、付多少,快照与反向操作两条撤销路的内存差 |
| 设计模式——解释器:解释还是编译 | 语法树求值与编译成闭包为什么打平,Pattern.compile 每次编译贵在哪 |
| 设计模式——中介者:谁负责协调 | N² 引用换成 N 的收益,以及中介者自己变成热点之后多线程吞吐掉多少 |
| 设计模式——备忘录:快照的代价 | 全量快照、增量日志、写时拷贝三条路的快照耗时、常驻内存与回滚耗时 |
| 设计模式——迭代器:分配与逃逸分析 | 迭代器分配什么时候被标量替换掉,什么时候逃逸成真实分配 |
| 设计模式——访问者:类型与操作的矩阵 | 类型轴与操作轴哪一边先长,两个扩展方向各改多少文件,每次分派差多少纳秒 |
| 设计模式——模板方法:钩子的成本 | 空钩子的数量什么时候开始花钱,默认实现里的逐字节退化 |
不在 GoF 里,但算同一类问题
| 文章 | 回答的问题 |
|---|---|
| 设计模式——对象池:什么时候是负优化 | 分配成本与同步成本的交叉点在几个线程,什么对象才值得池化 |
| 设计模式——不可变与防御性拷贝 | 共享与拷贝这两笔账怎么算,List.copyOf 与 unmodifiableList 差在哪 |
与 Java 系列的关系
模式是语言表达力的补丁,判断一个模式还要不要用,得先看今天的语法给到了什么。这条线与 Java 系列 共用同一批实测环境,语言特性那一组文章是本文集的前置阅读。
阅读建议
先看总纲,那篇给出判据并附三组对照实验,其余二十五篇都在它划出的框架里展开。想找具体问题的答案就直接翻对应那篇:每篇开头是问题与结论,中间是实验设计和原始数据,结尾是判断顺序。




