TL;DR(30 秒扫完)
- Spring 设计模式三分类:创建型(单例/工厂/抽象工厂/建造者)、结构型(代理/装饰器/适配器/外观)、行为型(模板/观察者/策略/责任链/中介者/状态)
- 七大原则:SOLID 五大原则(SRP/OCP/LSP/ISP/DIP)+ CRP + LOD
- OCP 定义:对修改关闭,对扩展开放(不是"对继承开放")
- 可维护性模式:减少变更(策略/代理/观察者)、消除重复(模板/工厂/建造者)、简化调用点(外观/责任链)
- 反过度设计:克制使用是判断标准——一年内大概率要改 3 次以上才抽象
关键结论
结论 A(三分类)Spring 设计模式分三类——创建型(单例/工厂/抽象工厂/建造者)、结构型(代理/装饰器/适配器/外观)、行为型(模板/观察者/策略/责任链/中介者/状态)
结论 B(七大原则)SOLID 五大原则(SRP/OCP/LSP/ISP/DIP)+ CRP + LOD
结论 C(OCP 定义)对修改关闭,对扩展开放(不是"对继承开放")
结论 D(可维护性模式)减少变更(策略/代理/观察者)、消除重复(模板/工厂/建造者)、简化调用点(外观/责任链)
结论 E(反过度设计)克制使用是判断标准——一年内大概率要改 3 次以上才抽象
完整讲解(费曼四步)
STEP 1 · 概念(一句话定义)
- 设计模式:解决特定场景下重复出现的设计问题的最佳实践
- Spring 设计模式:Spring 框架中广泛使用的设计模式,用于实现 IoC、AOP、MVC 等核心功能
- SOLID 原则:面向对象设计的五大基本原则(SRP/OCP/LSP/ISP/DIP)
STEP 2 · 大白话(生活类比)
类比(设计模式):就像做菜的"菜谱"——同样是做红烧肉(解决特定问题),不同的菜谱(设计模式)有不同的步骤和技巧(实现方式),但目标都是做出好吃的红烧肉(提高代码可维护性)。
STEP 3 · 底层(细节 + 代码/表格)
3.1 Spring 设计模式三分类完整清单
| 分类 | 模式 | Spring 实现类名 | 典型场景 |
|---|---|---|---|
| 创建型 | 单例 | BeanFactory | 默认 Bean 作用域是 singleton |
| 工厂方法 | FactoryBean | 自定义 Bean 创建逻辑 | |
| 抽象工厂 | ApplicationContext | 提供各种类型的 Bean | |
| 建造者 | @Bean 方法 | 构建复杂 Bean | |
| 结构型 | 代理 | AbstractAutoProxyCreator | AOP 代理(JDK/CGLIB) |
| 装饰器 | ServletRequestWrapper | 增强请求/响应 | |
| 适配器 | AbstractApplicationContext | 适配不同配置源 | |
| 外观 | ApplicationContext | 提供统一的 Bean 访问接口 | |
| 行为型 | 模板方法 | JdbcTemplate | 简化 JDBC 操作 |
| 观察者 | ApplicationEvent | 事件驱动(@EventListener) | |
| 策略 | PlatformTransactionManager | 事务管理策略 | |
| 责任链 | HandlerInterceptor | 请求处理链 | |
| 中介者 | ApplicationContext | 协调各组件交互 | |
| 状态 | TransactionStatus | 事务状态管理 |
3.2 七大原则(SOLID + CRP + LOD)
| 原则 | 缩写 | 定义 | 违反案例 |
|---|---|---|---|
| 单一职责 | SRP | 一个类只做一件事 | 一个类既有 CRUD 又有导出 Excel 又有权限校验 |
| 开闭原则 | OCP | 对修改关闭,对扩展开放 | 添加新功能需要修改现有代码 |
| 里氏替换 | LSP | 子类能替换父类不破坏契约 | 子类覆盖了父类方法导致行为不一致 |
| 依赖倒置 | DIP | 高层不依赖低层,都依赖抽象 | 高层模块依赖低层模块的具体实现 |
| 接口隔离 | ISP | 客户端不依赖不用的接口 | 一个接口包含多个不相关的方法 |
| 合成复用 | CRP | 优先组合而非继承 | 通过继承复用代码,导致类层次过深 |
| 迪米特法则 | LOD | 对象对其他对象有最少知识 | 调用链路过长(a.b.c.d()) |
- ❌ 错误:"对继承开放"
- ✅ 正确:"对扩展开放"
3.3 七大原则深度讲解
LSP 经典反例:正方形 vs 矩形class Rectangle {
void setWidth(int w) { this.width = w; }
void setHeight(int h) { this.height = h; }
int getArea() { return width * height; }
}
class Square extends Rectangle { // ❌ 违反 LSP
void setWidth(int w) {
this.width = w;
this.height = w; // 破坏父类契约
}
void setHeight(int h) {
this.width = h;
this.height = h; // 破坏父类契约
}
}
// 使用矩形
void process(Rectangle r) {
r.setWidth(5);
r.setHeight(4);
System.out.println(r.getArea()); // 期望 20
}
// 传入正方形
process(new Square()); // 输出 16,破坏行为契约!
核心:子类不能破坏父类的行为契约,否则调用者替换后会出错。
DIP 落地方式:面向接口编程
// ❌ 违反 DIP:高层直接依赖低层具体实现
class OrderService {
private MySQLDao dao = new MySQLDao(); // 依赖具体实现
}
// ✅ 符合 DIP:都依赖抽象
class OrderService {
private Dao dao; // 依赖抽象
public OrderService(Dao dao) {
this.dao = dao; // 构造函数注入
}
}
interface Dao {
void save();
}
class MySQLDao implements Dao { ... }
class OracleDao implements Dao { ... }
核心:高层模块不依赖低层模块,两者都依赖抽象。
LOD vs SRP:独立原则
- SRP:一个对象只负责一件事(关于一个对象的职责)
- LOD:一个对象对其他对象有最少的知识(关于对象之间的耦合)
// ❌ 违反 LOD:a 知道了 b、c、d 太多
String city = a.getB().getC().getD().getCity();
// ✅ 符合 LOD:a 只调用 b 的方法,由 b 返回 city
String city = a.getCity();
核心:减少对象之间的耦合,不要知道当前所需要的信息之外的信息。
LOD 不是 SRP 的延伸,它们是独立的原则:- SRP 关注单个对象的职责
- LOD 关注对象之间的耦合度
3.4 提高代码可维护性的模式
| 维度 | 模式 | 核心收益 | 适用场景 |
|---|---|---|---|
| 减少变更 | 策略 | 通过扩展策略类,而非修改现有代码 | 多种算法/业务逻辑的切换 |
| 代理 | 在方法不改动的情况下对方法实行扩展 | AOP 切面、权限控制 | |
| 观察者 | 事件驱动,解耦发送者和接收者 | 日志、通知、事件处理 | |
| 消除重复 | 模板方法 | 定义算法骨架,子类实现细节 | 数据处理流程、批量任务 |
| 工厂 | 简化对象创建,提供统一的创建入口 | 复杂对象创建、依赖注入 | |
| 建造者 | 分步骤构建复杂对象 | 配置对象、复杂对象组装 | |
| 简化调用点 | 外观 | 提供统一的接口,隐藏复杂子系统 | 简化第三方库调用 |
| 责任链 | 将请求沿处理链传递,每个处理器处理自己的部分 | 请求处理、校验链 |
3.4 反过度设计
克制使用原则:一年内大概率要改 3 次以上才抽象 反过度设计案例:- 简单 CRUD 强用策略:只有一个业务逻辑,却定义了策略接口和多个实现类
- 只有两个实现也上策略接口:只有两个实现,用 if-else 更简单
- 大量工厂+策略+建造者堆叠:形成"过度抽象",代码难以理解
- 代理:控制对对象的访问(权限、日志、缓存)
- 装饰器:动态给对象添加职责(增强功能)
- 享元:共享细粒度对象,减少内存占用(字符串常量池)
STEP 4 · 简化(比喻/口诀)
三分类口诀:创建型(单工建)、结构型(代适外)、行为型(模观策责中介状)(3 类 16 个模式记 3 句话)。
七大原则口诀:SRP 单一、OCP 开闭、LSP 里氏、ISP 隔离、DIP 倒置、CRP 合成、LOD 迪米特(7 个原则记 7 个字)。
OCP 定义口诀:对修改关闭,对扩展开放(不是继承)。
可维护性口诀:减少变更(策略/代理/观察者)、消除重复(模板/工厂/建造者)、简化调用点(外观/责任链)(3 维度 8 模式记 3 句话)。
反过度设计口诀:一年内改 3 次以上才抽象(克制使用)。
速查表
Spring 设计模式三分类 · 创建型(单工建)· 结构型(代适外)· 行为型(模观策责中介状)
七大原则 · SRP 单一 · OCP 开闭 · LSP 里氏 · ISP 隔离 · DIP 倒置 · CRP 合成 · LOD 迪米特
OCP 定义 · 对修改关闭,对**扩展**开放(不是继承)
LSP 反例 · 正方形继承矩形(破坏行为契约)
DIP 落地 · 面向接口编程(高层不依赖低层,都依赖抽象)
LOD 区别 · 不是 SRP 的延伸(对象间耦合 vs 单个对象职责)
可维护性模式 · 减少变更(策略/代理/观察者)· 消除重复(模板/工厂/建造者)· 简化调用点(外观/责任链)
反过度设计 · 一年内改 3 次以上才抽象(克制使用)
常见错点:Spring 用享元模式 ❌ / OCP 对继承开放 ❌ / 7 大原则只记得 1 个 ❌ / 所有模式都能提高可维护性 ❌ / LOD 是 SRP 延伸 ❌
Anki 候选卡片
Q: Spring 设计模式的三分类是什么?
A: 创建型(单例/工厂/抽象工厂/建造者)、结构型(代理/装饰器/适配器/外观)、行为型(模板/观察者/策略/责任链/中介者/状态)
Q: 设计模式的 7 大基本原则是什么?
A: SOLID 五大原则(SRP/OCP/LSP/ISP/DIP)+ CRP + LOD
Q: OCP 的定义是什么?
A: 对修改关闭,对扩展开放(不是"对继承开放")
Q: SRP 的定义是什么?
A: 单一职责原则——一个类只做一件事
Q: LSP 的定义是什么?
A: 里氏替换原则——子类能替换父类不破坏契约(经典反例:正方形继承矩形)
Q: DIP 的定义是什么?
A: 依赖倒置原则——高层不依赖低层,都依赖抽象(落地方式:面向接口编程)
Q: CRP 的定义是什么?
A: 合成复用原则——优先组合而非继承
Q: LOD 的定义是什么?
A: 迪米特法则——对象对其他对象有最少知识(不是 SRP 的延伸)
Q: 哪些设计模式可以提高代码可维护性?
A: 减少变更(策略/代理/观察者)、消除重复(模板/工厂/建造者)、简化调用点(外观/责任链)
Q: 如何避免过度设计?
A: 克制使用是判断标准——一年内大概率要改 3 次以上才抽象
关联题目
- [ ] 《Spring 中用到了哪些设计模式》—— 2026-09-28 Round 1, 评分 ⭐⭐⭐
- [ ] 《设计模式的 7 大基本原则有哪些?》—— 2026-09-28 Round 1, 评分 ⭐⭐
- [ ] 《使用哪种设计模式可以提高代码可维护性?》—— 2026-09-28 Round 1, 评分 ⭐⭐⭐⭐
- [ ] 《什么是设计模式?有什么好处?》—— 2026-10-08 Round 1, 评分 ⭐⭐⭐
- [ ] 《请简述 MVC 模式的思想》—— 2026-10-08 Round 1, 评分 ⭐⭐⭐
关联知识
Spring 设计模式三分类、SOLID 五大原则 + CRP + LOD、提高代码可维护性的模式
✦ 记 忆 口 诀 ✦
创建型单工建 / 结构型代适外 / 行为型模观策责中介状 / 七大原则七字记
关键可视化
暂无可视化
知识关系
🔄 延伸(Extends)
暂无⚡ 对比(Contrast)
暂无
🎯 概念
📏 规则
⚠️ 误区
🔍 追问
✨ 口诀
共 0 张卡,点击翻面