设计模式
Design Patterns
📖这门课到底讲什么
设计模式总结面向对象设计中反复出现的解决方案:以 GoF 二十三种模式为框架,涵盖创建型(单例、工厂方法、抽象工厂、建造者、原型)、结构型(适配器、装饰器、代理、外观、桥接、组合、享元)与行为型(观察者、策略、模板方法、责任链、命令、状态、迭代器、中介者、访问者等),并延伸到并发与架构层面的模式(生产者消费者、发布订阅、MVC、依赖注入)。课程强调模式背后的意图、适用场景与代价,而非套用名词。学完你应能从已有代码中识别可抽象点、用模式改善可扩展性、读懂主流框架中的模式应用,并能判断何时不该使用模式以避免过度设计。
🎯为什么必须学好
面试中高频出现:你了解哪些设计模式、项目里用过哪些、单例的几种实现与线程安全、策略模式与工厂模式的区别、如何把一堆 if-else 改成可扩展结构。阅读开源框架(Spring、MyBatis、Netty)几乎处处是模式,不做设计模式训练会看不懂源码。它是从能写功能到能设计模块的能力跃迁,也是技术面试区分中级与初级工程师的常见标尺。
📌核心知识清单
- 面向对象设计原则回顾:SOLID、组合优于继承、面向接口编程、开闭原则在模式中的体现
- 创建型模式:单例(饿汉、懒汉、双重检查、枚举与线程安全问题)、工厂方法与抽象工厂、建造者、原型与浅拷贝深拷贝
- 结构型模式:适配器与外观的区别、装饰器与代理的区别(静态代理与动态代理)、桥接、组合、享元
- 行为型模式(一):策略、模板方法、观察者(与事件驱动、发布订阅的关系)、责任链(与过滤器链的对应)
- 行为型模式(二):命令(与撤销重做)、状态机与状态模式、迭代器、中介者、访问者、备忘录
- 并发与架构模式:生产者消费者、读写锁、线程池、发布订阅、异步回调与 Promise、MVC/MVVM、依赖注入与容器
- 模式的应用与反模式:在框架中的真实应用(Spring 的工厂与代理、JDK 的装饰器与观察者)、过度设计与模式的滥用、模式组合使用
- 重构与模式:用模式消除条件分支、用多态替换条件、从代码坏味道到模式选择、模式与重构的配合
✍️怎么学(可执行步骤)
- 主线读《设计模式:可复用面向对象软件的基础》(GoF)第1章与第3至5章的经典模式,同时用《Head First 设计模式》建立直观理解(其场景故事很有助记忆)
- 每个模式都手写一遍最小可运行示例(不抄书),并写一段注释说明意图、适用场景与代价,用同一份代码库迭代(如从简单订单系统演化到支持策略与装饰的订单系统)
- 读 JDK 与 Spring 源码中的模式应用:InputStream 的装饰器、Collections 的工厂与适配器、Spring 的 BeanFactory 与 AOP 代理,写一篇《框架中的设计模式》笔记
- 做一次反模式练习:找一个满是 if-else 与重复代码的小项目,用策略、工厂与模板方法重构,记录重构前后类图与代码行数变化
📚推荐教材与书籍
模式的原始经典,第1章导论与第3至5章具体模式必读,案例偏向早期风格需要有耐心
用故事与图讲模式,轻松易记,适合第一遍建立印象,之后再回读 GoF
与模式互补,先有坏味道的识别再有模式的应用,是最实用的工程书之一
用重构视角讲模式与设计原则的关系,适合读过 GoF 后深入
🎬视频课程 / 公开课
国内高校课程,逐个模式配代码示例,与 Java 项目结合紧密
可跟随系统课程逐个模式敲代码,建议每个模式都自己实现一次
🌐网站与文档
中文图解设计模式,每个模式配意图、问题、解决方案与代码,学习效率最高的资源
二十四类代码坏味道清单,识别需要重构与模式介入的信号
🐙GitHub 开源资料
二十三种模式的完整 Java 实现与说明,含适用场景与代码,是本课最佳配套仓库
Python 版模式实现,代码短小清晰,适合快速对照理解意图
其中设计模式与框架部分可以看清模式在后端工程中的落点
🧪动手实践任务
实践 1
用同一个小项目(订单与支付)实现三种演进版本:第一版用 if-else 判断支付方式,第二版引入策略与简单工厂,第三版加入装饰器与责任链处理优惠与风控,写出三版类图与对比说明
实践 2
实现单例的五种写法(饿汉、懒汉、双重检查、静态内部类、枚举),用多线程测试验证线程安全并输出测试结果
实践 3
阅读 JDK 或 Spring 的一段源码并写分析报告,指出其中使用了哪些模式、解决了什么问题、代价是什么
实践 4
完成一次重构实践:选一个课程项目模块,用重构手法(提炼方法、多态替换条件、引入策略)消除重复与长分支,并用手写测试保证行为不变
🧾考试与面试
💼 面试会怎么考
高频:介绍一下你熟悉的设计模式并在项目中的使用场景;单例的实现方式与线程安全、为什么推荐枚举;策略模式与工厂模式的区别与配合;如何用模式消除大量 if-else;装饰器与代理的区别;观察者模式与发布订阅的区别;责任链在实际框架中的应用(过滤器、拦截器);什么是依赖注入与 IOC 容器;反问:如果一个需求用不上模式你会怎么写(考是否反对过度设计)。Java 岗尤其爱考这些。
📝 期末与考研怎么过
期末多为简答与设计题:说明某模式的意图、结构与适用场景并画类图;给出业务场景让你选择合适模式并实现;代码阅读题让你识别所用模式;论述题比较相似模式(策略与状态、适配器与桥接、装饰器与代理)。备考方式是把每类模式的类图与一个可运行示例背熟,考试时先判断意图再套结构。目标八十五分以上。
⚠️ 常见坑
- 为了用模式而用模式,简单逻辑硬套上工厂加策略加单例,代码比原来更复杂,这是最常见的过度设计
- 只记模式名字与类图,说不清意图与代价,面试被追问适用场景就露馅
- 混淆相似模式:策略与状态、适配器与外观、装饰器与代理,答错说明理解停留在背诵层面
- 学完不用,项目中依旧写超长方法与大量条件分支;应把重构与模式结合起来练习
- 忽略并发安全,单例与享元在并发场景下出现状态共享问题