整理自设计模式面试题 14 道,已精简冗余表述。详细原理见 设计模式概述。
相关学习笔记
| 专题 | 笔记 |
|---|---|
| 设计模式概述 | 设计模式概述 |
| 创建型 | 创建型模式 |
| 结构型 | 结构型模式 |
| 行为型 | 行为型模式 |
| Spring AOP | Spring AOP 与事务 |
目录
基础与原则
1. 什么是设计模式
一套被反复使用、多数人知晓、经过分类编目的代码设计经验总结。目的是:可重用代码、易于理解、保证可靠性、提高程序重用性。
2. 为什么要学习设计模式
- 阅读 JDK、Spring、MyBatis 等源码时理解其结构
- 接手遗留项目时读懂前辈代码
- 编写可维护、可扩展的业务代码
3. 设计模式分类
| 类型 | 数量 | 常见模式 |
|---|---|---|
| 创建型 | 5 | 工厂方法、抽象工厂、单例、建造者、原型 |
| 结构型 | 7 | 适配器、装饰器、代理、外观、桥接、组合、享元 |
| 行为型 | 11 | 策略、模板方法、观察者、责任链、命令、状态等 |
→ 设计模式概述
4. 设计模式六大原则
| 原则 | 要点 |
|---|---|
| 开闭原则 | 对扩展开放,对修改关闭 |
| 里氏替换 | 子类可扩展父类,不破坏父类非抽象行为 |
| 依赖倒置 | 面向接口编程,依赖抽象不依赖具体 |
| 接口隔离 | 多个专用接口优于单一臃肿接口 |
| 迪米特法则 | 最少知道,降低类间耦合 |
| 单一职责 | 一个类/方法只负责一类变化 |
创建型模式
5. 单例模式
定义:保证一个类只有一个实例,并提供全局访问点。
应用场景:计数器、日志组件、线程池、Windows 任务管理器/回收站等。
实现方式:
| 方式 | 特点 |
|---|---|
| 饿汉式 | 类加载即创建,线程安全,无懒加载 |
| 懒汉式 | 用时创建,需考虑线程安全(synchronized/DCL) |
| 静态内部类 | 懒加载 + 线程安全,推荐 |
| 枚举 | JVM 保证单例,防反射/反序列化,无懒加载 |
选型:不需懒加载 → 枚举或饿汉式(枚举更优);需懒加载 → 静态内部类优于懒汉式。
注意:慎用反射破坏单例;懒汉式注意并发;滥用可能导致连接池溢出、状态丢失。
6. 工厂模式
定义:将对象创建与使用分离,客户端通过统一接口获取产品,无需关心具体创建逻辑。
三种形态:
| 类型 | 说明 |
|---|---|
| 简单工厂 | 一个工厂类根据参数创建不同产品;易违反开闭原则 |
| 工厂方法 | 抽象工厂 + 具体工厂,每个产品对应一个工厂;易扩展 |
| 抽象工厂 | 工厂的工厂,创建一族相关产品(如汽车 + 发动机) |
Spring 应用:IOC 容器本质是工厂,通过反射创建 Bean 放入 Map,实现单例管理与解耦。
7. 建造者模式
定义:将复杂对象构建与表示分离,同一构建过程可创建不同表示。
角色:Builder(规范步骤)、ConcreteBuilder(实现步骤)、Director(编排顺序)、Product(产品)。
场景:复杂对象、属性相互依赖、需控制装配顺序。StringBuilder 是典型应用。
与工厂区别:工厂关注创建什么对象;建造者关注如何分步组装。
8. 原型模式
定义:通过克隆已有实例创建新对象,避免重复 expensive 的初始化。
场景:创建成本高、需保护性拷贝、Spring 多例 Bean。
实现:实现 Cloneable,重写 clone();注意浅拷贝与深拷贝(引用类型需单独 clone)。
结构型模式
9. 代理模式
定义:为对象提供代理,在调用前后增强功能(AOP 思想)。
分类:
| 类型 | 说明 |
|---|---|
| 静态代理 | 编译期生成代理类,需为每个目标写代理 |
| JDK 动态代理 | 基于接口 + 反射,Proxy.newProxyInstance |
| CGLIB 代理 | 字节码子类代理,可代理类,不能代理 final |
Spring 应用:AOP、事务、日志、权限控制。MyBatis Mapper 常用 JDK 动态代理。
区别:静态代理需手写;JDK 代理必须有接口;CGLIB 可代理类但不可继承 final。
10. 外观模式
定义:为子系统一组复杂接口提供统一简化入口(门面),隐藏内部复杂性。
场景:注册后需依次调用短信、邮件、微信推送;门面封装 sendMsg(),客户端只调一门面方法。
与代理区别:外观是结构简化;代理是增强/控制访问。
行为型模式
11. 模板方法模式
定义:父类定义算法骨架(模板方法),部分步骤延迟到子类实现(抽象方法)。
场景:流程固定、个别步骤可变。如 Servlet 的 doGet/doPost、JUnit 测试框架、JDBC 模板。
示例:餐厅模板——看菜单(固定)→ 点菜(子类)→ 吃饭(固定)→ 付款(子类)→ 走人(固定)。
12. 策略模式
定义:封装一系列算法/逻辑,使它们可互换,简化 if-else。
场景:会员折扣(初级/中级/高级)、支付方式(微信/支付宝/银联)。
优点:算法自由切换、避免多重条件、易扩展。
缺点:策略类增多、需对外暴露。
结构:抽象策略 + 具体策略 + Context 维护当前策略。
13. 观察者模式
定义:一对多依赖,主题状态变化时自动通知所有观察者(发布-订阅)。
职责:1 对 N 通知;推模式(广播)或拉模式(观察者自主拉取)。
场景:事件驱动、消息队列、GUI 监听、Spring 事件机制。
结构:Subject(注册/移除/通知)、Observer(update)、ConcreteObserver、ConcreteSubject。
14. 设计模式在 Spring 中的综合应用
| Spring 特性 | 相关模式 |
|---|---|
| IOC 容器 | 工厂、单例 |
| AOP | 代理 |
JdbcTemplate | 模板方法 |
事件 ApplicationListener | 观察者 |
| Bean 作用域 prototype | 原型 |
面试常问:能说出模式名称、解决什么问题、Spring 哪里用到,并对比相似模式(工厂 vs 建造者、代理 vs 装饰器、策略 vs 状态)。