
前言
偶然间翻开书架上那本GoF
(四人帮 )经典,已经开始吃灰了!入行十余年了,大大小小也经历了不少公司。回想过往,刚接手很多公司的代码时,仓库里充斥着臃肿的Service
、难以测试的紧耦合 、还有为模式而模式的"炫技式"
写法 !吾日三省吾身:我们真的"懂"
了吗?还是仅仅记住了几个名字?
本系列文章,不是来复述那23
个模式定义------市面上早泛滥了! 我们剑指痛点:系统化! 要把设计原则 的"道"
与设计模式 的"术"
串联起来,打碎那些孤立的"知识点"
,让你在真实项目的泥潭里能游刃有余,写出健壮、灵活又不失优雅的代码。
操千曲 而后晓声,观千剑 而后识器。虐它千百遍 方能通晓其真意。
现实中常见的问题
搞Java
的,谁没被面试官问过"工厂模式和抽象工厂模式有啥区别?" 或者"讲讲你项目中用到的设计模式?" 多数时候,答案是不是像背八股文?SOLID?
哦,听说过!开闭原则?接口隔离?好像有点模糊... 真正用到项目里?啧... 🤷♂️
问题出在哪?孤岛效应! 学模式像收集邮票,只记得这个叫"单例",那个叫"观察者",然后... 没了?😱 至于为啥用它?上下文是什么?收益成本咋衡量? 手一抖,就把一个单例(Singleton
)硬怼进Controller
层?为了"解耦"强行塞进策略模式 ,结果代码复杂度飙升? 悲剧往往就这么酿成的!
设计模式,本质是前辈们踩坑踩出来的"最佳实践"
记录 📝。但它们只是"招式"
! 就像练功夫,只学"形"(招式)不练"气"(原则),花架子而已,实战分分钟被揍趴!设计原则 (SOLID
、DRY
、KISS
、LoD
等)就是我们的"内功心法"💪。
举个栗子:没练好"单一职责(SRP
)"的底气,搞啥策略模式?没"依赖倒置(DIP
)"的支撑,工厂模式怎么玩得溜?
原则是地基,模式是建立在它之上的房子框架!
要想真正掌握设计原则和模式的精髓,我们需要通过构建系统的学习路径和实战方法,将他们掰开了、揉碎了,最终建立属于自己的知识体系!目标就一个:
让你学得明白,用得顺手,拒绝纸上谈兵!拒绝一学就会,一用就废!! 💪
构建知识体系四步法:别急着盖楼,先打牢地基
!🏗️

想象一下,你要盖栋好房子(写出优雅健壮的系统)。能上来就琢磨用啥花纹的瓷砖(具体模式 )或者搞个罗马柱(架构风格 )吗?绝对塌给你看! 咱得按部就班,一层层来:

编程基础:你的砖瓦水泥
!🧱
啥意思? 上述图中的核心知识你得玩得溜!不是背概念,是真能在键盘上噼里啪啦敲出来,理解背后的 "为什么?"
为啥重要? 设计原则和模式,都是用这些 "基础积木" 搭出来的!连interface
和abstract class
都分不清,谈啥依赖倒置 (DIP
)?多态玩不转,策略模式 (Strategy
)对你就是天书!
地基不牢,地动山摇! 别嫌烦,回头补课也得补扎实了!
设计原则:房子的钢筋骨架
! (SOLID
是核心!)

核心是啥? SOLID
五兄弟。还有 DRY
(别重复自己)、KISS
(保持简单)、LoD
(最少知识,别瞎打听) 这些好基友。
为啥是骨架? 它们定义了"好代码"的底层逻辑和约束!
SRP
告诉你一个类别啥都管(否则就是"上帝类",等着被唾弃吧!👻);OCP
教你拥抱变化(改需求?别动老代码,加新的!);DIP
让你摆脱紧耦合(高层别依赖底层细节,都依赖抽象!)。
没这些原则打底,设计模式就是无根浮萍,用起来准变形! 它们是评判代码好坏、选择模式的金标准!
设计模式:解决特定问题的户型图和施工方案
!📐
终于到模式了!
- 创建型 :
怎么优雅地造对象?
工厂、单例、建造者...。 - 结构型 :
对象怎么组合?
适配器、装饰器、代理、组合...。 - 行为型 :
对象间怎么沟通协作?
策略、观察者、命令、状态、模板方法...。
为啥是户型图?
每个模式,都是前辈们在特定场景下摸索出的、经过验证的最佳实践"蓝图"。比如:
- 需要灵活创建对象。
- 需要动态添加功能。
- 需要解耦发送者和接收者。
它们直接应用了底层的设计原则!比如:
- 工厂模式 (
Factory
)是DIP
的典型体现; - 策略模式 (
Strategy
)完美诠释了OCP
; - 装饰器模式 (
Decorator
)玩的就是组合优于继承(LSP
的一种体现)。
看懂户型图(模式),你才知道怎么在钢筋骨架(原则)上砌墙!
架构模式:整个小区的规划和风格
!🏘️

宏观视角! 上图中常用的架构模式,是更高层次的代码组织方式,定义了模块职责 、通信机制 和数据流。
为啥放最后? 架构模式建立在大量设计模式和原则的基础上!比如:
MVC
里Controller
协调View
和Model
,常用到策略、命令模式。- 事件驱动架构的核心就是观察者模式。
- 分层架构要求层间依赖清晰(
DIP
!)。
没掌握好原则和基础模式,强行搞架构?那就是空中楼阁,分分钟烂尾! 架构模式是水到渠成的结果,不是起点。
小结
上述四层是环环相扣、逐层支撑 的!跳过基础学模式?学不明白!绕过原则玩架构?玩不转!系统化学习,就得按这个层次来,一层一层吃透! 别想着一步登天,那都是忽悠新手的!🙅♂️
渐进式掌握路线:练功要讲章法,别贪多嚼不烂
!🥋
知道了要学啥层次,那具体怎么练 ?贪多求全,把23+
模式一股脑塞进脑子?保证你消化不良,走火入魔! 咱得讲究个循序渐进,重点突破。
筑基期:死磕 SOLID
原则!🔥🔥🔥 (这是内功心法!)

目标: 不是背定义,是让这些原则刻进骨髓里!写代码时下意识就会用它们衡量。
怎么练?
1️⃣ 单一职责原则(Single Responsiblility Principle,SRP
)
看到几千行的Service
类就想吐?那就对了!强迫自己拆分!一个类只为一个"改变的理由"负责。想想:修改用户信息和发送通知能放一起吗?🤔
2️⃣ 开闭原则(Open-Closed Principle, OCP
)
新需求来了,是改老代码还是加新类/接口?对修改关闭,对扩展开放! 多用抽象(接口、抽象类),多用组合。举个栗子:支付方式增加,别改老支付逻辑,加个新实现类!
3️⃣ 里式替换原则:(Listov Substitution Principle,LSP
)
子类必须能完全替换父类!别在子类里加强前置条件、削弱后置条件、或者抛出父类没声明的异常。Rectangle
和 Square
的继承就是个经典坑!🚨
4️⃣ 接口隔离原则(Interface Segregation Principle, ISP
)
接口别太"胖"!客户端不该被迫依赖它用不上的方法。大接口?拆!拆成更小、更聚焦的接口。别让UserService
接口既有login
又有generateReport
!
5️⃣ 依赖倒置原则(Dependence Inversion Principle,DIP
)
高层模块别依赖低层模块!都依赖抽象! Service
里别 new DaoImpl()
,依赖 Dao
接口!让Spring/IoC
容器帮你注入具体实现。这是解耦的核心!
为啥先练这个? 原则是模式之魂! 不理解
SOLID
,学模式就是学个"形",知其然不知其所以然,用起来必然生硬甚至错误。这个阶段练好了,后面学模式事半功倍!
通玄期:拿下 8 个核心模式
!🎯 (这是常用招式!)

目标: 精通常见、高频、且最能体现原则的模式,形成战斗力!
💎 精选哪8
个?(理由充分!)
模式 | 核心价值 | 原则映射 | 应用频率 | 典型应用场景 |
---|---|---|---|---|
工厂/抽象工厂 | 对象创建的解放者 : 隐藏复杂构造逻辑,让调用方只依赖抽象,而非具体实现类 | **✅ DIP (核心)** : 高层模块不依赖低层细节 ✅ SRP :创建职责被隔离 |
⭐⭐⭐⭐ (极高) | • Spring @Bean • 多数据库驱动切换 • 支付方式动态创建 |
单例 | 全局唯一哨兵 : 确保一个类只有一个实例,提供统一访问入口 | **✅ 误用违反SRP/LoD ** : 滥用易成"全局状态垃圾场" ✅ 合理使用符合DRY/KISS |
⭐⭐⭐ (慎用) | • 配置管理 • 线程池/连接池 • Spring 单例Bean |
适配器 | 接口的翻译官 : 让不兼容的接口协同工作,实现无缝集成 | ✅ ISP (核心) :为客户端定制接口 ✅ 组合优于继承:优先组合而非强行继承原有类 |
⭐⭐⭐ (中等) | • 旧系统接口适配 • 第三方库接口统一封装 • 不同日志框架桥接 |
装饰器 | 功能的动态扩展包 : 运行时透明添加职责,避免继承导致的类爆炸 | ✅ OCP (典范) :扩展开放,修改关闭 ✅ 组合优于继承:功能叠加如乐高 |
⭐⭐⭐ (中等) | • Java I/O 流 (BufferedInputStream ) • Spring 缓存装饰 (@Cachable ) • 中间件增强 |
代理 | 对象的门神与管家 : 控制访问、增强功能、替本体执行辅助操作 | ✅ SRP (核心) :分离核心逻辑与管控职责 ✅ DIP :客户端依赖抽象代理 |
⭐⭐⭐⭐ (极高) | • Spring AOP 动态代理 • MyBatis Mapper 接口代理 • 安全代理(权限校验) |
观察者 | 事件的广播塔 : 解耦事件源与处理方,实现一对多动态通知 | ✅ LoD (最少知识) :发布者不感知处理方 ✅ 高内聚低耦合:事件机制天然解耦 |
⭐⭐⭐⭐ (极高) | • GUI 事件处理 • Spring 事件监听机制 • 订单状态变更通知 • 消息队列消费模型 |
策略 | 算法的自由交换机 : 封装算法族,运行时灵活切换策略 | **✅ OCP/DIP (黄金组合)**: 新增策略不影响主体 抽象策略 → 具体实现依赖倒置 |
⭐⭐⭐⭐ (极高) | • 支付方式切换 • 促销规则计算 • 排序算法动态选择 |
模板方法 | 流程的骨架师 : 父类定义算法框架,子类实现可变步骤 | **✅ 代码复用** :固定流程复用 ✅ OCP :通过子类扩展细节,不修改骨架 |
⭐⭐⭐ (中等) | • Servlet.service() 流程控制 • 工作流引擎步骤封装 • 游戏初始化框架 |
高频模式深度解读 🔥🔥🔥:
1️⃣ 工厂/代理/观察者/策略 → 四大天王!
- 为什么高频? 直接解决 解耦 、扩展 、动态性 三大痛点!
- 工厂:
new
是耦合毒药!工厂是解药!(Spring
: 我就是药厂!💊) - 代理:
AOP
基石!没它?日志、事务、安全都得硬编码! - 观察者: 事件驱动架构的灵魂!现代异步系统的血脉!
- 策略: 业务多变的救星!支付、营销、风控... 策略一招鲜!
2️⃣ 单例双刃剑 ⚔️:
- 容器托管优先!
Spring
单例Bean
≠ 手写Singleton
模式! - 硬需求才用: 真·全局唯一资源(如物理设备句柄)。
- 测试灾难区: 全局状态让单元测试互相污染!
Mock
?难如登天!
3️⃣ 适配器/装饰器/模板方法 → 场景化专家!
- 适配器: 旧系统改造、异构整合的"和事佬"。
- 装饰器:
I/O
增强、透明扩展的"隐形战衣"。 - 模板方法: 框架设计者最爱的"标准化流水线"。
为啥是这8个? 它们覆盖了创建、结构、行为三大类,应用场景极其广泛 ,是其他模式的基础或常与之组合。更重要的是,它们与
SOLID
原则的绑定关系清晰可见 !吃透它们,就掌握了设计模式的"核心战斗力"。
合道期:扩展其他模式 & 融会贯通
!🚀

目标: 在核心模式运用自如的基础上,根据项目需要,有选择地 学习其他模式,并理解模式间的联系与组合。
怎么学?
1️⃣ 带着问题学: 项目中遇到特定痛点(比如状态流转复杂?试试状态模式+策略组合!需要撤销操作?命令模式了解一下!),再去研究对应的模式。
2️⃣ 对比与关联: 工厂方法 vs
抽象工厂?适配器 vs
装饰器 vs
代理?策略 vs
状态?理解它们的细微差别和适用场景。
3️⃣ 模式组合拳: 真实项目很少只用单一模式!观察者通知状态改变,状态机内部用策略选择行为... 学会打组合拳才是高手! 🥊
4️⃣ 警惕反模式: 识别并避免滥用模式(如过度设计、为模式而模式)。
为啥放最后? 有了前两阶段的坚实基础(原则内化 + 核心模式熟练),再学其他模式会更容易理解其意图、优缺点和适用性 ,也能更自然地思考如何组合运用。此时学习,效率最高,理解最深!
小结
上述框架的精髓在于:
1️⃣ 层次分明,根基稳固: 从基础到原则到模式再到架构,层层递进,缺一不可 。别妄想跳过SOLID
就能玩转模式!
2️⃣ 聚焦核心,以点带面: 先死磕 SOLID
和 8
大核心模式,形成扎实的"设计直觉"和"工具箱"。贪多嚼不烂是新手大忌!
3️⃣ 原则驱动,理解本质: 学模式时,时刻问:它体现了哪个/哪些设计原则?解决了什么痛点? 脱离原则的模式是空壳!
4️⃣ 实战为王,学以致用: 所有学习最终都要落到写代码、重构代码、解决实际问题上!看懂了不算,写出来、用对了才算!💻
深度学习方法论:把知识"腌"入味
!🧠💥
别指望看几篇博客就能成高手!设计原则和模式得 用、使劲用、变着花样用,还得不断感悟、反思、回顾及总结! 这套方法论,专治一学就会,一用就废!
原则学习三维度:别当"知道分子",要做"实践派"
!

维度 | 学习要点 (灵魂拷问!) | 实践方法 (来点狠的!) |
---|---|---|
概念本质 | 这破原则到底图个啥? 它解决啥痛点?没它会死吗?跟其他原则啥关系? | 残酷对比! 找段祖传屎山代码,把违反原则的灾难现场和遵守原则的优雅版本放一起对比! 感受那扎心的差距:维护成本、可测性、灵活性... 天壤之别! |
识别场景 | 什么时候该它出场了? 闻到代码里啥"坏味道",就该搬出这个原则了? | 建你的"原则雷达"清单! SRP 报警:类超500 行?方法干多个事? OCP 报警:加新功能必须改旧代码? DIP 报警:高层类里遍地new XXXImpl() ? 遇到这种场景,马上想:噢!该请【某某原则】出来洗地了! |
实践边界 | 用过头了会咋死? 会不会杀鸡用牛刀?过度设计也是病! | 刻意练习"走钢丝"! 简单场景狠用原则: 写个"计算器",也硬拆接口,搞多实现,用工厂创建... 感受下"杀鸡用牛刀"的繁琐! 明白 YAGNI 原则 (You Ain't Gonna Need It ) 的真理! 复杂场景挑战原则边界: 在真实稍复杂的模块里(如订单处理),思考:为OCP 搞抽象层,代价(类爆炸?认知负担?)是否值得? 在"灵活"和"简单"之间找黄金分割点!没有银弹,只有trade-off ! |
学原则不是背教条! 要像老中医
"望闻问切"
:识别代码坏味道(望闻 )→ 判断适用原则(问 )→ 开出处方(切 )→ 还得跟踪疗效,防止药太猛(过度设计)! 🌿
模式学习黄金三角:拆骨架、配场景、掂分量
!🔱
学模式?记类图是远远不够的!掌握这个"金三角"
,你才算真正"懂"
一个模式:

具体实施?刀刀见血!
1️⃣ 解构模式骨架:把它扒光,看透本质! (比类图更狠!)
- 核心目标: 用最直白的代码,拎出模式最核心的角色、关系和交互逻辑!剔除所有装饰性代码。
- 栗子:观察者模式,骨子里就三句话!
java
// 1️⃣ 定义核心角色:谁是"被观察者"(Subject)? 谁是"观察者"(Observer)?
public interface Subject {
void registerObserver(Observer observer); // 动态注册观察者
void removeObserver(Observer observer); // 动态移除观察者
void notifyObservers(); // 观察者喊话:有事,速来!
}
// 2️⃣ 定义交互协议
public interface Observer {
void update(String event); // 观察者说:收到!我处理!
}
// 3️⃣ 实现具体联动:被观察者怎么管观察者名单?怎么喊话?
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>(); // 小本本记下所有挂号的人
// 🔥 重点看这个联动点!遍历名单,挨个喊"update!"
public void notifyObservers() {
for (Observer o : observers) {
o.update("出大事了!速看!");
}
}
}
2️⃣ 场景匹配练习:别只会"Hello World"
例子!玩真实!
- 核心目标: 把模式骨架,"投射"到你身边真实业务逻辑上!找那种 "非它不可"或"用它超爽" 的场景。
- 栗子:电商订单状态变更 (观察者模式的绝配!)
[真实痛点] 订单支付成功,需要立刻:扣库存、发短信通知用户、给财务系统记账、可能触发优惠券核销... 怎么让订单模块不变成"管家婆"?
✅ 观察者模式出手!
- 订单中心 (
Subject
/ 发布者): 负责订单状态流转。状态变更时,大喊一声:notifyObservers(OrderStatusChangeEvent)
! - 库存服务 (
Observer
/ 订阅者1): 实现update
方法,收到事件,检查事件类型,如果是"支付成功",则扣减库存! - 短信服务 (
Observer
/ 订阅者2): 实现update
,收到事件,给用户发成功短信! - 财务记账服务 (
Observer
/ 订阅者3): 实现update
,进行财务处理... - 优惠券服务 (
Observer
/ 订阅者4): ...(你懂的)
❌ 其他模式为啥不行?
- 单例: 能提供实例,但解决不了"动态通知多个模块"的问题!订单中心还得一个个调他们!
- 工厂: 能创建对象,但和"事件通知"八竿子打不着!
场景匹配的关键在于 ------ "解耦"!
发布者(订单中心)完全不知道、也不关心有多少订阅者、他们具体干啥!只知道状态变了自己就喊一嗓子!新加个订阅者(比如:大数据分析服务)?订单中心一行代码都不用改!
OCP
原则发光发热!这就是威力!💥别拿模式硬套所有场景,要像选工具一样:"这把螺丝刀,就最适合拧这种螺丝!"
3️⃣ 优劣评估:掂量清楚!不是啥仙丹
!
- 高光时刻 (
Pros
):- 松耦合王者! 发布者、订阅者完全独立发展,互不干扰。系统弹性蹭蹭涨!
- 动态增删订阅者?
So easy
!registerObserver
/removeObserver
随时安排!扩展性爆表! - 广播通知?天生一对! 一个事件,多方响应。
- 隐秘角落 (
Cons
):- 更新顺序?玄学! 订阅者被通知的顺序可能不可控(如:
List
遍历顺序)。财务记账必须在扣库存前完成?那你得自己加额外机制(如:优先级),模式本身不保证! - 内存泄露幽灵! 订阅者忘了
removeObserver
?发布者会一直持有它的引用,导致订阅者无法被GC
回收!尤其匿名内部类!警惕!(栗子:Android Handler
内存泄露经典案!) - 调试噩梦? 事件满天飞,流程像断了线的风筝🪁。
A
通知B
,B
的处理逻辑又通知了C
... 找源头?链条长了让人崩溃!分布式环境下更甚! 消息跟踪是必备技能! - 性能开销? 遍历所有订阅者通知,尤其有些处理耗时,可能导致发布者阻塞或系统吞吐下降!
- 更新顺序?玄学! 订阅者被通知的顺序可能不可控(如:
世界上没有完美的模式!只有适合不适合! 观察者模式在需要高效解耦事件源与处理方 的场景下是神器!但在事件处理流程要求强顺序、强事务、高性能 的场合,就得掂量掂量它的副作用了!可能得配合队列、事务消息、
Saga
等更复杂的方案!永远考虑trade-off
!
小结
- 原则三维度: 搞透"为啥要它?、啥时候用它?、用多猛合适? " 拒绝教条主义!
- 模式黄金三角: 拆透骨架 → 匹配真痛点 → 掂量优缺点! 脱离骨架是花架子,匹配错场景是瞎折腾,不看代价是愣头青!
- 实践!实践!还是实践! 看一百遍不如亲手写一遍(包括写烂的版本)。重构自己的代码或看看开源项目(
Spring
源码是宝藏!挖它!⛏️),找找哪里能用这些原则模式去优化!痛点,是最好的老师!
总结
Java
设计之道,在于打通"原则"与"模式"的任督二脉! 深入理解SOLID
等原则的底层力量,你才能真正领悟每种模式诞生的缘由和应用边界。模式不是银弹! 会选、会用、会组合,更要深知何时刹车------这才是高手的境界!🚀
这个系列文章,将带你摆脱"知识点孤岛",用真实代码说话,系统性地磨砺你的设计内功,让写出的代码不再是功能堆砌,而是匠心之作! 准备好,开启一场深度的设计思维训练了吗? 👉 🔥
欢迎一键四连 (
关注
+点赞
+收藏
+评论
)