作者:龙茶清欢
版本:v1.2(2025年更新)
适用对象:具备 Java 基础,希望提升架构能力、代码质量与系统可维护性的后端工程师
一、什么是设计模式?
✅ 定义:
设计模式(Design Pattern) 是在软件设计中,针对常见问题所提出的可复用的解决方案模板。它不是具体的代码,而是解决问题的思路、结构和最佳实践,由经验丰富的开发者总结提炼而来。
📌 经典定义(GoF):
“Design patterns are descriptions of communicating objects and classes that are customized to solve a general design problem in a particular context.”
——《Design Patterns: Elements of Reusable Object-Oriented Software》(GoF,1994)
🌰 举个生活中的例子:
- 就像“盖房子”有“砖混结构”、“框架结构”等标准方案,设计模式就是软件开发中的“建筑蓝图”。
- 比如:你每天早上要“泡咖啡”,你可以自己买咖啡豆磨、煮,也可以直接用“胶囊咖啡机”——后者就是一种“模式”:封装了复杂流程,提供统一接口。
二、设计模式有什么作用?(Why Use Design Patterns?)
| 作用维度 | 说明 |
|---|---|
| ✅ 提升代码可维护性 | 模式结构清晰,命名规范,他人容易理解你的设计意图。 |
| ✅ 增强代码复用性 | 模式是通用解决方案,可在不同项目中复用,减少重复造轮子。 |
| ✅ 降低耦合度,提高内聚性 | 通过接口隔离、依赖倒置等原则,使模块间松散耦合。 |
| ✅ 提升系统扩展性 | 如工厂模式、策略模式,新增功能无需修改已有代码(开闭原则)。 |
| ✅ 促进团队协作 | 团队成员使用相同模式术语(如“单例”、“观察者”),沟通成本低。 |
| ✅ 面试与架构能力加分 | 面试官常问设计模式,掌握它是晋升架构师的必备技能。 |
| ✅ 规避常见设计陷阱 | 如避免“上帝类”、过度继承、硬编码等反模式(Anti-pattern)。 |
💡 一句话总结:
设计模式 = 软件工程中的“成语” —— 用标准表达,解决标准问题,让代码“言之有物”。
三、何时使用设计模式?(When to Use)
✅ 正确使用时机:
| 场景 | 是否推荐使用模式 | 说明 |
|---|---|---|
| 代码重复、逻辑臃肿 | ✅ 强烈推荐 | 用策略模式、模板方法等解耦 |
| 系统需要频繁扩展新功能 | ✅ 推荐 | 如新增支付方式 → 策略模式 |
| 对象创建复杂、配置多变 | ✅ 推荐 | 工厂模式、建造者模式 |
| 对象间存在一对多依赖 | ✅ 推荐 | 观察者模式(如事件通知) |
| 需要全局唯一实例 | ✅ 推荐 | 单例模式(注意线程安全) |
| 代码已稳定、无需变更 | ❌ 不推荐 | 过度设计(YAGNI 原则) |
| 小型脚本/临时工具 | ❌ 不推荐 | 增加复杂度,得不偿失 |
| 业务逻辑简单明确 | ⚠️ 谨慎 | 可先用简单实现,后续重构 |
⚠️ 注意:避免“模式滥用”(过早优化)
🚫 错误示范:
为了“显得专业”,在一个只有 3 行逻辑的工具类里硬套工厂模式。
✅ 正确做法:
先写简单代码 → 遇到痛点 → 识别模式 → 重构引入
这是“模式驱动重构”而非“模式驱动设计”。
四、设计模式基础与核心原则(SOLID + 其他)
设计模式的根基是面向对象设计原则。掌握这些原则,你才能真正理解模式为何如此设计。
✅ 1. SOLID 原则(五大核心)
| 原则 | 全称 | 说明 | 对应设计模式 |
|---|---|---|---|
| Single Responsibility Principle | 单一职责原则 | 一个类只负责一个功能领域 | 工厂模式、策略模式 |
| Open/Closed Principle | 开闭原则 | 对扩展开放,对修改关闭 | 策略模式、模板方法、装饰器 |
| Liskov Substitution Principle | 里氏替换原则 | 子类必须能替换父类而不影响程序正确性 | 所有继承/多态场景 |
| Interface Segregation Principle | 接口隔离原则 | 客户端不应依赖它不需要的接口 | 接口拆分 + 组合模式 |
| Dependency Inversion Principle | 依赖倒置原则 | 高层模块不应依赖低层模块,两者都应依赖抽象 | 工厂、抽象工厂、依赖注入 |
💡 记忆口诀:SOLID = 五条黄金法则
✅ 2. 其他重要设计原则
| 原则 | 说明 |
|---|---|
| Composition over Inheritance(组合优于继承) | 优先使用对象组合而非继承来复用代码,更灵活、避免继承层次爆炸 |
| LoD — Law of Demeter(迪米特法则) | 一个对象应尽量少地与其他对象发生相互作用,降低耦合 |
| YAGNI(You Aren’t Gonna Need It) | 不要提前设计你目前不需要的功能 |
| KISS(Keep It Simple, Stupid) | 保持简单,不要过度设计 |
| DRY(Don’t Repeat Yourself) | 避免重复代码,用模式抽象共性 |
🔍 重点推荐:组合优于继承 和 开闭原则 是设计模式的灵魂!
五、设计模式分类(23种经典模式)
根据 GoF(Gang of Four)分类,设计模式分为三大类:
| 类别 | 数量 | 目的 | 核心思想 |
|---|---|---|---|
| 创建型模式 | 5 种 | 对象如何创建 | 解耦对象创建与使用 |
| 结构型模式 | 7 种 | 类/对象如何组合 | 组织类与对象的结构 |
| 行为型模式 | 11 种 | 对象如何交互 | 定义对象之间的通信方式 |
📦 1. 创建型模式(5种) —— 解决“怎么创建对象”
| 模式 | 作用 | Java 示例 | 适用场景 |
|---|---|---|---|
| 单例(Singleton) | 保证一个类只有一个实例 | Runtime.getRuntime() | 配置管理、数据库连接池、日志器 |
| 工厂方法(Factory Method) | 定义创建对象的接口,由子类决定实例化哪个类 | Calendar.getInstance() | 多种产品,但创建逻辑统一 |
| 抽象工厂(Abstract Factory) | 创建一系列相关或依赖对象的家族 | javax.sql.DataSource | 多套UI主题、数据库驱动切换 |
| 建造者(Builder) | 分步构建复杂对象 | StringBuilder、AlertDialog.Builder | 对象属性多、构造复杂(如POJO、SQL语句) |
| 原型(Prototype) | 通过复制现有对象创建新对象 | Object.clone() | 对象创建成本高,需频繁复制(如缓存对象) |
✅ 后端常用:单例、工厂方法、建造者 最高频
🧱 2. 结构型模式(7种) —— 解决“如何组合对象”
| 模式 | 作用 | Java 示例 | 适用场景 |
|---|---|---|---|
| 适配器(Adapter) | 将一个接口转换成客户期望的另一个接口 | java.util.Arrays#asList() | 第三方库接口不兼容时 |
| 桥接(Bridge) | 将抽象与实现分离,使它们可独立变化 | JDBC 驱动与数据库连接 | 多维度扩展(如数据库+驱动+连接池) |
| 组合(Composite) | 将对象组合成树形结构以表示“部分-整体” | javax.swing.JComponent | 文件系统、菜单树、组织架构 |
| 装饰器(Decorator) | 动态给对象添加额外职责 | java.io.InputStream 包装类 | 日志、缓存、加密等横切关注点 |
| 外观(Facade) | 为复杂子系统提供统一接口 | javax.persistence.EntityManager | 微服务调用多个内部服务时封装 |
| 享元(Flyweight) | 共享大量细粒度对象以节省内存 | String.intern()、Integer缓存 | 高并发下大量重复对象(如字符、颜色) |
| 代理(Proxy) | 为其他对象提供代理以控制访问 | java.lang.reflect.Proxy、Spring AOP | 权限控制、延迟加载、远程调用 |
✅ 后端常用:装饰器、外观、代理 最实用(尤其在 Spring AOP 中)
🤝 3. 行为型模式(11种) —— 解决“对象如何通信”
| 模式 | 作用 | Java 示例 | 适用场景 |
|---|---|---|---|
| 责任链(Chain of Responsibility) | 多个对象处理请求,形成链条 | javax.servlet.Filter | 多个拦截器(权限、日志、限流) |
| 命令(Command) | 将请求封装为对象,支持撤销、队列 | java.lang.Runnable | 操作回滚、任务队列、宏命令 |
| 解释器(Interpreter) | 定义语言文法,解释表达式 | java.util.regex.Pattern | 少用,用于DSL解析 |
| 迭代器(Iterator) | 提供统一方式遍历集合 | java.util.Iterator | 遍历自定义集合 |
| 中介者(Mediator) | 用一个中介对象封装对象间交互 | java.util.concurrent.ExecutorService | 多对象通信复杂时,如聊天室 |
| 备忘录(Memento) | 在不破坏封装前提下捕获对象内部状态 | java.io.Serializable | 撤销操作、游戏存档 |
| 观察者(Observer) | 一对多依赖,对象状态改变时通知所有依赖者 | java.util.Observable / java.beans.PropertyChangeListener | 事件驱动系统、消息推送 |
| 状态(State) | 允许对象在内部状态改变时改变行为 | java.nio.channels.Channel | 状态机(订单状态:待支付→已支付→已发货) |
| 策略(Strategy) | 定义一系列算法,封装并使它们可互换 | java.util.Comparator | 支付方式、折扣策略、排序算法 |
| 模板方法(Template Method) | 定义算法骨架,子类重写某些步骤 | java.util.Collections#sort() | 抽象流程(如订单处理流程) |
| 访问者(Visitor) | 在不修改元素类的前提下,定义新操作 | javax.lang.model.element.ElementVisitor | 复杂对象结构遍历(AST解析) |
✅ 后端高频使用:
策略、模板方法、观察者、责任链、命令 —— 这5种是后端开发最核心的5大行为模式
六、设计模式实战案例(Java 后端场景)
🌟 案例1:支付系统 —— 策略模式 + 工厂模式
// 策略接口
public interface PaymentStrategy {
boolean pay(double amount);
}
// 具体策略
public class AlipayStrategy implements PaymentStrategy { ... }
public class WeChatPayStrategy implements PaymentStrategy { ... }
// 工厂类
public class PaymentFactory {
public static PaymentStrategy getStrategy(String type) {
switch (type) {
case "alipay": return new AlipayStrategy();
case "wechat": return new WeChatPayStrategy();
default: throw new IllegalArgumentException();
}
}
}
// 使用
PaymentStrategy strategy = PaymentFactory.getStrategy("alipay");
strategy.pay(100.0);
✅ 优势:新增支付方式,只需新增类,无需改原有代码(开闭原则)
🌟 案例2:日志系统 —— 装饰器模式
public class LoggingDecorator extends OutputStream {
private OutputStream target;
public LoggingDecorator(OutputStream out) { this.target = out; }
@Override
public void write(int b) throws IOException {
System.out.println("Writing byte: " + b); // 日志
target.write(b);
}
}
// 使用
OutputStream file = new FileOutputStream("log.txt");
OutputStream logged = new LoggingDecorator(file);
✅ 优势:动态添加日志、压缩、加密等能力,无需修改原始类
🌟 案例3:订单流程 —— 模板方法 + 状态模式
public abstract class OrderProcess {
public final void process() {
validate();
calculateTotal();
applyDiscount(); // 子类可重写
save();
notifyUser();
}
protected abstract void applyDiscount(); // 钩子方法
}
public class RegularOrderProcess extends OrderProcess {
@Override protected void applyDiscount() { /* 无折扣 */ }
}
public class VIPOrderProcess extends OrderProcess {
@Override protected void applyDiscount() { /* 10% off */ }
}
✅ 优势:固定流程不变,灵活扩展业务逻辑
七、设计模式学习路径建议(4步走)
| 阶段 | 目标 | 建议行动 |
|---|---|---|
| 1. 理解概念 | 知道“是什么” | 通读本指南,理解SOLID原则 |
| 2. 掌握高频模式 | 能写出、能解释 | 重点掌握:单例、工厂、策略、模板方法、观察者、装饰器、代理 |
| 3. 项目实战 | 在真实代码中使用 | 在你的 Spring Boot 项目中重构:把 if-else 改成策略模式 |
| 4. 深入源码 | 看懂大师如何用 | 阅读:java.util.Collections, java.io, Spring Framework 中的模式应用 |
✅ 推荐阅读源码:
java.util.Collections#sort()→ 模板方法java.io.InputStream→ 装饰器java.util.concurrent.ExecutorService→ 工厂 + 命令Spring AOP→ 代理模式Spring BeanFactory→ 工厂 + 单例
八、设计模式的“现代演进”与替代方案
| 传统模式 | 现代替代/补充 |
|---|---|
| 单例模式 | Spring 的 @Component + @Scope("singleton") |
| 工厂模式 | Spring 的 @Bean + 依赖注入 |
| 策略模式 | Java 8+ Lambda + Function<T, R> |
| 观察者模式 | RxJava、Reactor、Spring Event |
| 装饰器 | Java 8 Stream Pipeline、AOP切面 |
| 命令模式 | Spring Task、消息队列(RabbitMQ/Kafka) |
💡 关键认知:
设计模式不是过时的,而是思想的体现。
现代框架(Spring、Netty、Reactor)内部大量使用设计模式,只是被封装了。
你的任务是:看懂它们,用好它们,而不是重复造轮子。
九、学习资源推荐
| 类型 | 推荐资源 |
|---|---|
| 📚 书籍 | 《Head First 设计模式》(通俗易懂) 《Java与模式》(阎宏) 《设计模式:可复用面向对象软件的基础》(GoF) |
| 🎥 视频 | B站:《Java设计模式精讲》(黑马程序员) YouTube:“Design Patterns in 10 Minutes” |
| 💻 实战 | GitHub 搜索:java design patterns examples推荐项目:https://github.com/iluwatar/java-design-patterns |
| 🧪 练习 | LeetCode 设计模式题(如“实现一个线程安全的单例”) 用策略模式重构你项目的“折扣计算”逻辑 |
十、总结:设计模式的终极价值
| 维度 | 设计模式带来的价值 |
|---|---|
| 代码质量 | 更清晰、更健壮、更易测试 |
| 团队协作 | 统一语言,降低沟通成本 |
| 系统扩展 | 新功能插入成本低,不易破坏旧逻辑 |
| 职业成长 | 面试加分项,架构师必备技能 |
| 思维提升 | 从“写代码”到“设计系统” |
✅ 记住这句话:
“好的代码不是写出来的,是设计出来的。”
设计模式,就是你设计能力的“工具箱”。
✅ 附录:快速查表 —— 后端常用设计模式速查
| 场景 | 推荐模式 |
|---|---|
| 多种支付方式 | 策略模式 |
| 创建复杂对象(如SQL、JSON) | 建造者模式 |
| 日志、权限、缓存增强 | 装饰器模式 |
| 订单状态流转 | 状态模式 |
| 多个拦截器处理请求 | 责任链模式 |
| 统一调用多个服务 | 外观模式 |
| 事件通知(如订单创建后发短信) | 观察者模式 |
| 配置管理、数据库连接池 | 单例模式 |
| 创建不同数据库连接 | 工厂方法 / 抽象工厂 |
| 封装一个操作(如异步任务) | 命令模式 |
| 固定流程(如审核流程) | 模板方法 |
📌 最后建议:学习三步法
- 先用 —— 在项目中主动尝试用一个模式(哪怕只是改一行代码)
- 再想 —— 为什么用这个模式?不用会有什么问题?
- 后悟 —— 看源码,发现 Spring/MyBatis 里它怎么用的?这才是真正的掌握!
💬 你不是在学“模式”,你是在学“如何优雅地解决问题”。
掌握了设计模式,你就从“CRUD 工程师”成长为“系统架构思维者”。
下一步行动建议:
👉 选一个你最近写的类,尝试用“策略模式”重构它,然后写一篇总结发到团队内分享!


被折叠的 条评论
为什么被折叠?



